Updates

Update 2021.08.11

Most thorough way to readdress differences between original and current analyses is to jsut redo the biomark. To that end, will restart analysis of just CMPm2, excluding other datasets (i.e., LSK, MEP, GMP). Will also keep

Notebook setup

Creating new pipeline using seurat v4.0.2 available 2021.06.08

Load libraries required for Seuratv4

library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(Seurat)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Attaching SeuratObject
library(patchwork)
library(ggplot2)
library(clustree)
Loading required package: ggraph

Set global variables

projectName <- "CMP"
jackstraw.dim <- 40

store session info

sessionInfo.filename <- paste0(projectName, "_sessionInfo.txt")
sink(sessionInfo.filename)
sessionInfo()
sink()
source("../RFunctions/read_10XGenomics_data.R")
source("../RFunctions/PercentVariance.R")
source("../RFunctions/Mouse2Human_idconversion.R")
source ("../RFunctions/ColorPalette.R")
setwd("../../cellRanger/") # temporarily changing wd only works if you run the entire chunk at once
data_file.list <- read_10XGenomics_data(sample.list = "CMPm2")
object.data <-Read10X(data_file.list)
cmp.object<- CreateSeuratObject(counts = object.data, min.cells = 3, min.genes = 200, project = projectName)

Clean up to free memory

remove(object.data)

Add mitochondrial metadata and plot some basic features

cmp.object[["percent.mt"]] <- PercentageFeatureSet(cmp.object, pattern = "^mt-")
VlnPlot(cmp.object, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3, pt.size = 0, fill.by = 'orig.ident', )

plot1 <- FeatureScatter(cmp.object, feature1 = "nCount_RNA", feature2 = "percent.mt", group.by = "orig.ident", pt.size = 0.01)
plot2 <- FeatureScatter(cmp.object, feature1 = "nCount_RNA", feature2 = "nFeature_RNA", group.by = "orig.ident", pt.size = 0.01)
plot1 + plot2

Filter data

remove low quality cells require: nFeature_RNA between 200 and 4000 (inclusive) require: percent.mt <=5

print(paste("original object:", nrow(cmp.object@meta.data), "cells", sep = " "))
[1] "original object: 12540 cells"
cmp.object <- subset(cmp.object, 
                                                subset = nFeature_RNA >=200 & 
                                                    nFeature_RNA <= 4000 & 
                                                    percent.mt <= 5
                                                )
print(paste("new object:", nrow(cmp.object@meta.data), "cells", sep = " "))
[1] "new object: 12059 cells"
cmp.object <- NormalizeData(cmp.object, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

Find variable features

cmp.object <- FindVariableFeatures(cmp.object, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
top10 <- head(VariableFeatures(cmp.object), 10)
plot1 <- VariableFeaturePlot(cmp.object)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
When using repel, set xnudge and ynudge to 0 for optimal results
plot1 + plot2

Scale data (linear transformation)

We don’t have to worry about comparing library depths, so we’ll just do normalization/Scale data

Regressing out nFeature_RNA, nCount_RNA

  |                                                                                                                                                                                                                      
  |                                                                                                                                                                                                                |   0%
  |                                                                                                                                                                                                                      
  |=                                                                                                                                                                                                               |   0%
  |                                                                                                                                                                                                                      
  |=                                                                                                                                                                                                               |   1%
  |                                                                                                                                                                                                                      
  |==                                                                                                                                                                                                              |   1%
  |                                                                                                                                                                                                                      
  |===                                                                                                                                                                                                             |   1%
  |                                                                                                                                                                                                                      
  |===                                                                                                                                                                                                             |   2%
  |                                                                                                                                                                                                                      
  |====                                                                                                                                                                                                            |   2%
  |                                                                                                                                                                                                                      
  |=====                                                                                                                                                                                                           |   2%
  |                                                                                                                                                                                                                      
  |=====                                                                                                                                                                                                           |   3%
  |                                                                                                                                                                                                                      
  |======                                                                                                                                                                                                          |   3%
  |                                                                                                                                                                                                                      
  |=======                                                                                                                                                                                                         |   3%
  |                                                                                                                                                                                                                      
  |=======                                                                                                                                                                                                         |   4%
  |                                                                                                                                                                                                                      
  |========                                                                                                                                                                                                        |   4%
  |                                                                                                                                                                                                                      
  |=========                                                                                                                                                                                                       |   4%
  |                                                                                                                                                                                                                      
  |=========                                                                                                                                                                                                       |   5%
  |                                                                                                                                                                                                                      
  |==========                                                                                                                                                                                                      |   5%
  |                                                                                                                                                                                                                      
  |===========                                                                                                                                                                                                     |   5%
  |                                                                                                                                                                                                                      
  |===========                                                                                                                                                                                                     |   6%
  |                                                                                                                                                                                                                      
  |============                                                                                                                                                                                                    |   6%
  |                                                                                                                                                                                                                      
  |=============                                                                                                                                                                                                   |   6%
  |                                                                                                                                                                                                                      
  |==============                                                                                                                                                                                                  |   6%
  |                                                                                                                                                                                                                      
  |==============                                                                                                                                                                                                  |   7%
  |                                                                                                                                                                                                                      
  |===============                                                                                                                                                                                                 |   7%
  |                                                                                                                                                                                                                      
  |================                                                                                                                                                                                                |   7%
  |                                                                                                                                                                                                                      
  |================                                                                                                                                                                                                |   8%
  |                                                                                                                                                                                                                      
  |=================                                                                                                                                                                                               |   8%
  |                                                                                                                                                                                                                      
  |==================                                                                                                                                                                                              |   8%
  |                                                                                                                                                                                                                      
  |==================                                                                                                                                                                                              |   9%
  |                                                                                                                                                                                                                      
  |===================                                                                                                                                                                                             |   9%
  |                                                                                                                                                                                                                      
  |====================                                                                                                                                                                                            |   9%
  |                                                                                                                                                                                                                      
  |====================                                                                                                                                                                                            |  10%
  |                                                                                                                                                                                                                      
  |=====================                                                                                                                                                                                           |  10%
  |                                                                                                                                                                                                                      
  |======================                                                                                                                                                                                          |  10%
  |                                                                                                                                                                                                                      
  |======================                                                                                                                                                                                          |  11%
  |                                                                                                                                                                                                                      
  |=======================                                                                                                                                                                                         |  11%
  |                                                                                                                                                                                                                      
  |========================                                                                                                                                                                                        |  11%
  |                                                                                                                                                                                                                      
  |========================                                                                                                                                                                                        |  12%
  |                                                                                                                                                                                                                      
  |=========================                                                                                                                                                                                       |  12%
  |                                                                                                                                                                                                                      
  |==========================                                                                                                                                                                                      |  12%
  |                                                                                                                                                                                                                      
  |==========================                                                                                                                                                                                      |  13%
  |                                                                                                                                                                                                                      
  |===========================                                                                                                                                                                                     |  13%
  |                                                                                                                                                                                                                      
  |============================                                                                                                                                                                                    |  13%
  |                                                                                                                                                                                                                      
  |============================                                                                                                                                                                                    |  14%
  |                                                                                                                                                                                                                      
  |=============================                                                                                                                                                                                   |  14%
  |                                                                                                                                                                                                                      
  |==============================                                                                                                                                                                                  |  14%
  |                                                                                                                                                                                                                      
  |==============================                                                                                                                                                                                  |  15%
  |                                                                                                                                                                                                                      
  |===============================                                                                                                                                                                                 |  15%
  |                                                                                                                                                                                                                      
  |================================                                                                                                                                                                                |  15%
  |                                                                                                                                                                                                                      
  |================================                                                                                                                                                                                |  16%
  |                                                                                                                                                                                                                      
  |=================================                                                                                                                                                                               |  16%
  |                                                                                                                                                                                                                      
  |==================================                                                                                                                                                                              |  16%
  |                                                                                                                                                                                                                      
  |==================================                                                                                                                                                                              |  17%
  |                                                                                                                                                                                                                      
  |===================================                                                                                                                                                                             |  17%
  |                                                                                                                                                                                                                      
  |====================================                                                                                                                                                                            |  17%
  |                                                                                                                                                                                                                      
  |====================================                                                                                                                                                                            |  18%
  |                                                                                                                                                                                                                      
  |=====================================                                                                                                                                                                           |  18%
  |                                                                                                                                                                                                                      
  |======================================                                                                                                                                                                          |  18%
  |                                                                                                                                                                                                                      
  |======================================                                                                                                                                                                          |  19%
  |                                                                                                                                                                                                                      
  |=======================================                                                                                                                                                                         |  19%
  |                                                                                                                                                                                                                      
  |========================================                                                                                                                                                                        |  19%
  |                                                                                                                                                                                                                      
  |=========================================                                                                                                                                                                       |  19%
  |                                                                                                                                                                                                                      
  |=========================================                                                                                                                                                                       |  20%
  |                                                                                                                                                                                                                      
  |==========================================                                                                                                                                                                      |  20%
  |                                                                                                                                                                                                                      
  |===========================================                                                                                                                                                                     |  20%
  |                                                                                                                                                                                                                      
  |===========================================                                                                                                                                                                     |  21%
  |                                                                                                                                                                                                                      
  |============================================                                                                                                                                                                    |  21%
  |                                                                                                                                                                                                                      
  |=============================================                                                                                                                                                                   |  21%
  |                                                                                                                                                                                                                      
  |=============================================                                                                                                                                                                   |  22%
  |                                                                                                                                                                                                                      
  |==============================================                                                                                                                                                                  |  22%
  |                                                                                                                                                                                                                      
  |===============================================                                                                                                                                                                 |  22%
  |                                                                                                                                                                                                                      
  |===============================================                                                                                                                                                                 |  23%
  |                                                                                                                                                                                                                      
  |================================================                                                                                                                                                                |  23%
  |                                                                                                                                                                                                                      
  |=================================================                                                                                                                                                               |  23%
  |                                                                                                                                                                                                                      
  |=================================================                                                                                                                                                               |  24%
  |                                                                                                                                                                                                                      
  |==================================================                                                                                                                                                              |  24%
  |                                                                                                                                                                                                                      
  |===================================================                                                                                                                                                             |  24%
  |                                                                                                                                                                                                                      
  |===================================================                                                                                                                                                             |  25%
  |                                                                                                                                                                                                                      
  |====================================================                                                                                                                                                            |  25%
  |                                                                                                                                                                                                                      
  |=====================================================                                                                                                                                                           |  25%
  |                                                                                                                                                                                                                      
  |=====================================================                                                                                                                                                           |  26%
  |                                                                                                                                                                                                                      
  |======================================================                                                                                                                                                          |  26%
  |                                                                                                                                                                                                                      
  |=======================================================                                                                                                                                                         |  26%
  |                                                                                                                                                                                                                      
  |=======================================================                                                                                                                                                         |  27%
  |                                                                                                                                                                                                                      
  |========================================================                                                                                                                                                        |  27%
  |                                                                                                                                                                                                                      
  |=========================================================                                                                                                                                                       |  27%
  |                                                                                                                                                                                                                      
  |=========================================================                                                                                                                                                       |  28%
  |                                                                                                                                                                                                                      
  |==========================================================                                                                                                                                                      |  28%
  |                                                                                                                                                                                                                      
  |===========================================================                                                                                                                                                     |  28%
  |                                                                                                                                                                                                                      
  |===========================================================                                                                                                                                                     |  29%
  |                                                                                                                                                                                                                      
  |============================================================                                                                                                                                                    |  29%
  |                                                                                                                                                                                                                      
  |=============================================================                                                                                                                                                   |  29%
  |                                                                                                                                                                                                                      
  |=============================================================                                                                                                                                                   |  30%
  |                                                                                                                                                                                                                      
  |==============================================================                                                                                                                                                  |  30%
  |                                                                                                                                                                                                                      
  |===============================================================                                                                                                                                                 |  30%
  |                                                                                                                                                                                                                      
  |===============================================================                                                                                                                                                 |  31%
  |                                                                                                                                                                                                                      
  |================================================================                                                                                                                                                |  31%
  |                                                                                                                                                                                                                      
  |=================================================================                                                                                                                                               |  31%
  |                                                                                                                                                                                                                      
  |==================================================================                                                                                                                                              |  31%
  |                                                                                                                                                                                                                      
  |==================================================================                                                                                                                                              |  32%
  |                                                                                                                                                                                                                      
  |===================================================================                                                                                                                                             |  32%
  |                                                                                                                                                                                                                      
  |====================================================================                                                                                                                                            |  32%
  |                                                                                                                                                                                                                      
  |====================================================================                                                                                                                                            |  33%
  |                                                                                                                                                                                                                      
  |=====================================================================                                                                                                                                           |  33%
  |                                                                                                                                                                                                                      
  |======================================================================                                                                                                                                          |  33%
  |                                                                                                                                                                                                                      
  |======================================================================                                                                                                                                          |  34%
  |                                                                                                                                                                                                                      
  |=======================================================================                                                                                                                                         |  34%
  |                                                                                                                                                                                                                      
  |========================================================================                                                                                                                                        |  34%
  |                                                                                                                                                                                                                      
  |========================================================================                                                                                                                                        |  35%
  |                                                                                                                                                                                                                      
  |=========================================================================                                                                                                                                       |  35%
  |                                                                                                                                                                                                                      
  |==========================================================================                                                                                                                                      |  35%
  |                                                                                                                                                                                                                      
  |==========================================================================                                                                                                                                      |  36%
  |                                                                                                                                                                                                                      
  |===========================================================================                                                                                                                                     |  36%
  |                                                                                                                                                                                                                      
  |============================================================================                                                                                                                                    |  36%
  |                                                                                                                                                                                                                      
  |============================================================================                                                                                                                                    |  37%
  |                                                                                                                                                                                                                      
  |=============================================================================                                                                                                                                   |  37%
  |                                                                                                                                                                                                                      
  |==============================================================================                                                                                                                                  |  37%
  |                                                                                                                                                                                                                      
  |==============================================================================                                                                                                                                  |  38%
  |                                                                                                                                                                                                                      
  |===============================================================================                                                                                                                                 |  38%
  |                                                                                                                                                                                                                      
  |================================================================================                                                                                                                                |  38%
  |                                                                                                                                                                                                                      
  |================================================================================                                                                                                                                |  39%
  |                                                                                                                                                                                                                      
  |=================================================================================                                                                                                                               |  39%
  |                                                                                                                                                                                                                      
  |==================================================================================                                                                                                                              |  39%
  |                                                                                                                                                                                                                      
  |==================================================================================                                                                                                                              |  40%
  |                                                                                                                                                                                                                      
  |===================================================================================                                                                                                                             |  40%
  |                                                                                                                                                                                                                      
  |====================================================================================                                                                                                                            |  40%
  |                                                                                                                                                                                                                      
  |====================================================================================                                                                                                                            |  41%
  |                                                                                                                                                                                                                      
  |=====================================================================================                                                                                                                           |  41%
  |                                                                                                                                                                                                                      
  |======================================================================================                                                                                                                          |  41%
  |                                                                                                                                                                                                                      
  |======================================================================================                                                                                                                          |  42%
  |                                                                                                                                                                                                                      
  |=======================================================================================                                                                                                                         |  42%
  |                                                                                                                                                                                                                      
  |========================================================================================                                                                                                                        |  42%
  |                                                                                                                                                                                                                      
  |========================================================================================                                                                                                                        |  43%
  |                                                                                                                                                                                                                      
  |=========================================================================================                                                                                                                       |  43%
  |                                                                                                                                                                                                                      
  |==========================================================================================                                                                                                                      |  43%
  |                                                                                                                                                                                                                      
  |==========================================================================================                                                                                                                      |  44%
  |                                                                                                                                                                                                                      
  |===========================================================================================                                                                                                                     |  44%
  |                                                                                                                                                                                                                      
  |============================================================================================                                                                                                                    |  44%
  |                                                                                                                                                                                                                      
  |=============================================================================================                                                                                                                   |  44%
  |                                                                                                                                                                                                                      
  |=============================================================================================                                                                                                                   |  45%
  |                                                                                                                                                                                                                      
  |==============================================================================================                                                                                                                  |  45%
  |                                                                                                                                                                                                                      
  |===============================================================================================                                                                                                                 |  45%
  |                                                                                                                                                                                                                      
  |===============================================================================================                                                                                                                 |  46%
  |                                                                                                                                                                                                                      
  |================================================================================================                                                                                                                |  46%
  |                                                                                                                                                                                                                      
  |=================================================================================================                                                                                                               |  46%
  |                                                                                                                                                                                                                      
  |=================================================================================================                                                                                                               |  47%
  |                                                                                                                                                                                                                      
  |==================================================================================================                                                                                                              |  47%
  |                                                                                                                                                                                                                      
  |===================================================================================================                                                                                                             |  47%
  |                                                                                                                                                                                                                      
  |===================================================================================================                                                                                                             |  48%
  |                                                                                                                                                                                                                      
  |====================================================================================================                                                                                                            |  48%
  |                                                                                                                                                                                                                      
  |=====================================================================================================                                                                                                           |  48%
  |                                                                                                                                                                                                                      
  |=====================================================================================================                                                                                                           |  49%
  |                                                                                                                                                                                                                      
  |======================================================================================================                                                                                                          |  49%
  |                                                                                                                                                                                                                      
  |=======================================================================================================                                                                                                         |  49%
  |                                                                                                                                                                                                                      
  |=======================================================================================================                                                                                                         |  50%
  |                                                                                                                                                                                                                      
  |========================================================================================================                                                                                                        |  50%
  |                                                                                                                                                                                                                      
  |=========================================================================================================                                                                                                       |  50%
  |                                                                                                                                                                                                                      
  |=========================================================================================================                                                                                                       |  51%
  |                                                                                                                                                                                                                      
  |==========================================================================================================                                                                                                      |  51%
  |                                                                                                                                                                                                                      
  |===========================================================================================================                                                                                                     |  51%
  |                                                                                                                                                                                                                      
  |===========================================================================================================                                                                                                     |  52%
  |                                                                                                                                                                                                                      
  |============================================================================================================                                                                                                    |  52%
  |                                                                                                                                                                                                                      
  |=============================================================================================================                                                                                                   |  52%
  |                                                                                                                                                                                                                      
  |=============================================================================================================                                                                                                   |  53%
  |                                                                                                                                                                                                                      
  |==============================================================================================================                                                                                                  |  53%
  |                                                                                                                                                                                                                      
  |===============================================================================================================                                                                                                 |  53%
  |                                                                                                                                                                                                                      
  |===============================================================================================================                                                                                                 |  54%
  |                                                                                                                                                                                                                      
  |================================================================================================================                                                                                                |  54%
  |                                                                                                                                                                                                                      
  |=================================================================================================================                                                                                               |  54%
  |                                                                                                                                                                                                                      
  |=================================================================================================================                                                                                               |  55%
  |                                                                                                                                                                                                                      
  |==================================================================================================================                                                                                              |  55%
  |                                                                                                                                                                                                                      
  |===================================================================================================================                                                                                             |  55%
  |                                                                                                                                                                                                                      
  |===================================================================================================================                                                                                             |  56%
  |                                                                                                                                                                                                                      
  |====================================================================================================================                                                                                            |  56%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================                                                                                           |  56%
  |                                                                                                                                                                                                                      
  |======================================================================================================================                                                                                          |  56%
  |                                                                                                                                                                                                                      
  |======================================================================================================================                                                                                          |  57%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================                                                                                         |  57%
  |                                                                                                                                                                                                                      
  |========================================================================================================================                                                                                        |  57%
  |                                                                                                                                                                                                                      
  |========================================================================================================================                                                                                        |  58%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================                                                                                       |  58%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================                                                                                      |  58%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================                                                                                      |  59%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================                                                                                     |  59%
  |                                                                                                                                                                                                                      
  |============================================================================================================================                                                                                    |  59%
  |                                                                                                                                                                                                                      
  |============================================================================================================================                                                                                    |  60%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================                                                                                   |  60%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================                                                                                  |  60%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================                                                                                  |  61%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================                                                                                 |  61%
  |                                                                                                                                                                                                                      
  |================================================================================================================================                                                                                |  61%
  |                                                                                                                                                                                                                      
  |================================================================================================================================                                                                                |  62%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================                                                                               |  62%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================                                                                              |  62%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================                                                                              |  63%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================                                                                             |  63%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================                                                                            |  63%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================                                                                            |  64%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================                                                                           |  64%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================                                                                          |  64%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================                                                                          |  65%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================                                                                         |  65%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================                                                                        |  65%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================                                                                        |  66%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================                                                                       |  66%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================                                                                      |  66%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================                                                                      |  67%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================                                                                     |  67%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================                                                                    |  67%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================                                                                    |  68%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================                                                                   |  68%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================                                                                  |  68%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================                                                                  |  69%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================                                                                 |  69%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================                                                                |  69%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================                                                               |  69%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================                                                               |  70%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================                                                              |  70%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================                                                             |  70%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================                                                             |  71%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================                                                            |  71%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================                                                           |  71%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================                                                           |  72%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================================                                                          |  72%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================                                                         |  72%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================                                                         |  73%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================                                                        |  73%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================                                                       |  73%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================                                                       |  74%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================                                                      |  74%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================                                                     |  74%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================                                                     |  75%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================                                                    |  75%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================                                                   |  75%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================                                                   |  76%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================                                                  |  76%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================================                                                 |  76%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================================                                                 |  77%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================                                                |  77%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================================                                               |  77%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================================                                               |  78%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================================                                              |  78%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================================                                             |  78%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================================                                             |  79%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================================                                            |  79%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================================                                           |  79%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================================                                           |  80%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================================================                                          |  80%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================================                                         |  80%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================================                                         |  81%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================================                                        |  81%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================================                                       |  81%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================================                                      |  81%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================================                                      |  82%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================================                                     |  82%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================================                                    |  82%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================================                                    |  83%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================                                   |  83%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================================                                  |  83%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================================                                  |  84%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================================================                                 |  84%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================                                |  84%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================                                |  85%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================================================                               |  85%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================================================                              |  85%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================================================                              |  86%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================================================                             |  86%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================================================                            |  86%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================================================                            |  87%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================================================                           |  87%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================================================================                          |  87%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================================================================                          |  88%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================================================                         |  88%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================================================                        |  88%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================================================                        |  89%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================================================                       |  89%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================================================                      |  89%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================================================                      |  90%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================================================                     |  90%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================================================                    |  90%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================================================                    |  91%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================================                   |  91%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================================================                  |  91%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================================================                  |  92%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================================================================                 |  92%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================================                |  92%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================================                |  93%
  |                                                                                                                                                                                                                      
  |=================================================================================================================================================================================================               |  93%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================================================================              |  93%
  |                                                                                                                                                                                                                      
  |==================================================================================================================================================================================================              |  94%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================================================================             |  94%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================================================================            |  94%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================================================================           |  94%
  |                                                                                                                                                                                                                      
  |=====================================================================================================================================================================================================           |  95%
  |                                                                                                                                                                                                                      
  |======================================================================================================================================================================================================          |  95%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================================================================         |  95%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================================================================================         |  96%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================================================================        |  96%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================================================================       |  96%
  |                                                                                                                                                                                                                      
  |=========================================================================================================================================================================================================       |  97%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================================================================================================      |  97%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================================================================     |  97%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================================================================     |  98%
  |                                                                                                                                                                                                                      
  |============================================================================================================================================================================================================    |  98%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================================================   |  98%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================================================   |  99%
  |                                                                                                                                                                                                                      
  |==============================================================================================================================================================================================================  |  99%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================================================== |  99%
  |                                                                                                                                                                                                                      
  |=============================================================================================================================================================================================================== | 100%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================================================| 100%
Centering and scaling data matrix

  |                                                                                                                                                                                                                      
  |                                                                                                                                                                                                                |   0%
  |                                                                                                                                                                                                                      
  |============                                                                                                                                                                                                    |   6%
  |                                                                                                                                                                                                                      
  |========================                                                                                                                                                                                        |  12%
  |                                                                                                                                                                                                                      
  |=====================================                                                                                                                                                                           |  18%
  |                                                                                                                                                                                                                      
  |=================================================                                                                                                                                                               |  24%
  |                                                                                                                                                                                                                      
  |=============================================================                                                                                                                                                   |  29%
  |                                                                                                                                                                                                                      
  |=========================================================================                                                                                                                                       |  35%
  |                                                                                                                                                                                                                      
  |======================================================================================                                                                                                                          |  41%
  |                                                                                                                                                                                                                      
  |==================================================================================================                                                                                                              |  47%
  |                                                                                                                                                                                                                      
  |==============================================================================================================                                                                                                  |  53%
  |                                                                                                                                                                                                                      
  |==========================================================================================================================                                                                                      |  59%
  |                                                                                                                                                                                                                      
  |=======================================================================================================================================                                                                         |  65%
  |                                                                                                                                                                                                                      
  |===================================================================================================================================================                                                             |  71%
  |                                                                                                                                                                                                                      
  |===============================================================================================================================================================                                                 |  76%
  |                                                                                                                                                                                                                      
  |===========================================================================================================================================================================                                     |  82%
  |                                                                                                                                                                                                                      
  |========================================================================================================================================================================================                        |  88%
  |                                                                                                                                                                                                                      
  |====================================================================================================================================================================================================            |  94%
  |                                                                                                                                                                                                                      
  |================================================================================================================================================================================================================| 100%

Save raw object

saveRDS(cmp.object, file = paste0(projectName, "_raw.RDS"))
cmp.object <- RunPCA(cmp.object, features = VariableFeatures(cmp.object), ndims.print = 1:5, nfeatures.print = 5)
PC_ 1 
Positive:  Vamp5, Nkg7, Car2, Apoe, Ctla2a 
Negative:  Lgals3, Aif1, Id2, Cst3, H2-Aa 
PC_ 2 
Positive:  Prtn3, Ctsg, H2afy, Mpo, Emb 
Negative:  Ube2c, Cenpf, Nusap1, Mki67, Cenpa 
PC_ 3 
Positive:  Pf4, Tmsb4x, Cavin2, Serpine2, Rap1b 
Negative:  Plac8, Cks2, Cenpa, Ube2c, Tubb4b 
PC_ 4 
Positive:  Csrp3, Car1, Jun, Apoe, Jund 
Negative:  H2afz, Hmgn2, Birc5, Hmgb1, Tuba1b 
PC_ 5 
Positive:  Pclaf, Tyms, Rrm2, Tk1, Pcna 
Negative:  Hist1h2bc, Tsc22d1, Smim14, Ccnb2, Serpinb1a 
DimPlot(cmp.object, reduction = "pca", group.by = "orig.ident")

VizDimLoadings(cmp.object, dims = 1:6, nfeatures = 10, reduction = "pca", ncol = 3)

Calculate dimensionality

ElbowPlot(cmp.object, ndims = 50)
percent.variance(cmp.object@reductions$pca@stdev)

Number of PCs describing X% of variance

ElbowPlot(cmp.object, ndims = 50)

percent.variance(cmp.object@reductions$pca@stdev)

Add cluster IDs from Seurat v1

Exported cell IDs for clusters 3, 17, 10, 11 from Seurat v1. Will add these IDs as a metadata column.
Create column “clust.ID” and populate with 0’s. Then import IDs for clusters

tot.var <- percent.variance(cmp.object@reductions$pca@stdev, plot.var = FALSE, return.val = TRUE)
paste0("Num pcs for 80% variance:", length(which(cumsum(tot.var) <= 80)))
[1] "Num pcs for 80% variance:18"
paste0("Num pcs for 85% variance:", length(which(cumsum(tot.var) <= 85)))
[1] "Num pcs for 85% variance:25"
paste0("Num pcs for 90% variance:", length(which(cumsum(tot.var) <= 90)))
[1] "Num pcs for 90% variance:33"
paste0("Num pcs for 95% variance:", length(which(cumsum(tot.var) <= 95)))
[1] "Num pcs for 95% variance:41"

Add new metadata column

clust3.cells <- read.table(file = "../Seuratv1_clusterCellIDs/cluster3cellIDs.txt", col.names = "clust03")
clust3.cells <- sapply(clust3.cells, function(x) paste0(gsub("CMP", "CMPm2", x), "-1"))
clust17.cells <- read.table(file = "../Seuratv1_clusterCellIDs/cluster17cellIDs.txt", col.names = "clust17")
clust17.cells <- sapply(clust17.cells, function(x) paste0(gsub("CMP", "CMPm2", x), "-1"))
clust10.cells <- read.table(file = "../Seuratv1_clusterCellIDs/cluster10cellIDs.txt", col.names = "clust10")
clust10.cells <- sapply(clust10.cells, function(x) paste0(gsub("CMP", "CMPm2", x), "-1"))
clust11.cells <- read.table(file = "../Seuratv1_clusterCellIDs/cluster11cellIDs.txt", col.names = "clust11")
clust11.cells <- sapply(clust11.cells, function(x) paste0(gsub("CMP", "CMPm2", x), "-1"))

now map new ids

cmp.object@meta.data['clust.ID'] <- 0
head(cmp.object@meta.data)
Registered S3 method overwritten by 'cli':
  method     from         
  print.boxx spatstat.geom

do numbers make sense?

cmp.object@meta.data$clust.ID[rownames(cmp.object@meta.data) %in% clust3.cells] <- 3
cmp.object@meta.data$clust.ID[rownames(cmp.object@meta.data) %in% clust17.cells] <- 17
cmp.object@meta.data$clust.ID[rownames(cmp.object@meta.data) %in% clust10.cells] <- 10
cmp.object@meta.data$clust.ID[rownames(cmp.object@meta.data) %in% clust11.cells] <- 11

Total var 90%

Neighborhood and umap

set total.var <- 90%

nrow(cmp.object@meta.data[cmp.object@meta.data$clust.ID == 10,])
[1] 1049
nrow(cmp.object@meta.data[cmp.object@meta.data$clust.ID == 11,])
[1] 1118
nrow(cmp.object@meta.data[cmp.object@meta.data$clust.ID == 17,])
[1] 883
nrow(cmp.object@meta.data[cmp.object@meta.data$clust.ID == 3,])
[1] 1931

Plot UMAP

tot.var <- percent.variance(cmp.object@reductions$pca@stdev, plot.var = FALSE, return.val = TRUE)
ndims <- length(which(cumsum(tot.var) <= 90))

cmp.object <- FindNeighbors(cmp.object, dims = 1:ndims)
Computing nearest neighbor graph
Computing SNN
cmp.object <- FindClusters(cmp.object, resolution = 0.5)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8502
Number of communities: 9
Elapsed time: 1 seconds
cmp.object <- RunUMAP(cmp.object, dims = 1: ndims)
14:08:12 UMAP embedding parameters a = 0.9922 b = 1.112
14:08:12 Read 12059 rows and found 33 numeric columns
14:08:12 Using Annoy for neighbor search, n_neighbors = 30
14:08:12 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
14:08:13 Writing NN index file to temp file /var/folders/4f/fwrj6fnn1dn4g8wsf0zv563hjsvl24/T//Rtmp5gGDJN/file582a2b2d9d6c
14:08:14 Searching Annoy index using 1 thread, search_k = 3000
14:08:16 Annoy recall = 100%
14:08:17 Commencing smooth kNN distance calibration using 1 thread
14:08:17 Initializing from normalized Laplacian + noise
14:08:18 Commencing optimization for 200 epochs, with 513294 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
14:08:23 Optimization finished
for(x in c(0.5, 1, 1.5, 2, 2.5)){
    cmp.object <- FindClusters(cmp.object, resolution = x)
}
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8502
Number of communities: 9
Elapsed time: 1 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7974
Number of communities: 17
Elapsed time: 1 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7652
Number of communities: 22
Elapsed time: 1 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7404
Number of communities: 27
Elapsed time: 1 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 452999

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7189
Number of communities: 30
Elapsed time: 1 seconds
saveRDS(cmp.object, file = paste0(projectName, "_dim", ndims, ".RDS"))

Clustree

what’s the max resolution we can achieve while keepign clusters stable?

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        myplot <- DimPlot(cmp.object, 
                                            group.by = meta.col,
                                            reduction = "umap", 
                                            cols = color.palette
                                            ) + 
            ggtitle(paste0(projectName, " dim", ndims, "res", gsub("RNA_snn_res", "", meta.col) ))
        plot(myplot)
    }
}

I think I’m liking res.1.0 from this. Although how much does this change if I use fewer PCs…

for each resolution, number/percentage of cells in each cluster?

plot.title <- paste0(projectName, "_clustree_ndim", max(cmp.object@commands$RunUMAP.RNA.pca$dims))
my.clustree <- clustree(cmp.object, prefix = "RNA_snn_res.", node_colour = "sc3_stability", exprs = "scale.data") + 
    scale_color_continuous(low = 'red3', high = 'white') + 
    ggtitle(plot.title)
png(filename = paste0(plot.title, ".png"), height = 800, width = 1600)
plot(my.clustree)
dev.off()
null device 
          1 

For each resolution, what percentage of cells in each cluster are enriched for one of our clust.IDs?

Test: what percentage of each new clusterID matches one of the older clusters?

tot.cells <- nrow(cmp.object@meta.data)
for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        stats.df <- data.frame(matrix(ncol = 2, nrow = length(new.clusters)))
        colnames(stats.df) <- c("num_cells", "pct_pop")
        rownames(stats.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(stats.df)){
                num.x <- nrow(meta.df[meta.df[meta.col] == row.id,])
                pct.x <- as.integer(num.x / tot.cells *100)
                # print(pct.x)
                stats.df[row.id, "num_cells"] <- num.x
                stats.df[row.id, "pct_pop"] <- pct.x
        }
        print(stats.df)
    }
}

Absolutely terrible overlap, no enrichment of any of these across the new clustering algorithm. Maybe should try 95% variation covered

Find old cells on UMAP

time for the super scarey moment to see if the cells from seuratv1 still cluster together on in seurat v4

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        enrich.df <- data.frame(matrix(ncol = 4, nrow = length(new.clusters)))
        colnames(enrich.df) <- c(3, 17, 10, 11)
        rownames(enrich.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(enrich.df)){
            tot.clus <- nrow(meta.df[meta.df[[meta.col]] == row.id,])
            for(col.id in colnames(enrich.df)){
                num.x <- nrow(meta.df[(meta.df[[meta.col]] == row.id) & (meta.df$clust.ID == col.id),])
                pct.x <- as.integer(num.x / tot.clus *100)
                # print(pct.x)
                enrich.df[row.id, col.id] <- pct.x
            }
        }
        colnames(enrich.df) <- sapply(colnames(enrich.df), function(x) paste0("oldcluster", x))
        rownames(enrich.df) <- sapply(rownames(enrich.df), function(x) paste0("newcluster", x))
        xlsx::write.xlsx(enrich.df, file = paste0("PctOfNewClustersOverlappingOldClusters_", projectName, "_dim", ndims, ".xlsx"), sheetName = paste0(gsub("RNA_snn_", "", meta.col)), append = TRUE)
        print(enrich.df)
    }
}
NA
DimPlot(cmp.object,
                reduction = "umap",
                group.by = "clust.ID", 
                # split.by = "orig.ident",
                cols = c("gray", "orange", "blue", "red", "green"),)

Total var 85%

Neighborhood and umap

set total.var <- 85%

DimPlot(cmp.object,
                reduction = "umap",
                group.by = "orig.ident", 
                split.by = "clust.ID",
                cols = c("gray", "orange", "blue", "red", "green"),)

cmp.object <- FindNeighbors(cmp.object, dims = 1:ndims)
cmp.object <- FindClusters(cmp.object, resolution = 0.5)
cmp.object <- RunUMAP(cmp.object, dims = 1: ndims)

Plot UMAP

tot.var <- percent.variance(cmp.object@reductions$pca@stdev, plot.var = FALSE, return.val = TRUE)
ndims <- length(which(cumsum(tot.var) <= 85))

cmp.object <- FindNeighbors(cmp.object, dims = 1:ndims)
Computing nearest neighbor graph
Computing SNN
cmp.object <- FindClusters(cmp.object, resolution = 0.5)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8508
Number of communities: 9
Elapsed time: 2 seconds
cmp.object <- RunUMAP(cmp.object, dims = 1: ndims)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
10:37:55 UMAP embedding parameters a = 0.9922 b = 1.112
10:37:55 Read 12059 rows and found 25 numeric columns
10:37:55 Using Annoy for neighbor search, n_neighbors = 30
10:37:55 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
10:37:57 Writing NN index file to temp file /var/folders/4f/fwrj6fnn1dn4g8wsf0zv563hjsvl24/T//RtmpjY0Xgs/file912c3cf1e81b
10:37:57 Searching Annoy index using 1 thread, search_k = 3000
10:38:01 Annoy recall = 100%
10:38:01 Commencing smooth kNN distance calibration using 1 thread
10:38:02 Initializing from normalized Laplacian + noise
10:38:02 Commencing optimization for 200 epochs, with 500658 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
for(x in c(0.5, 1, 1.5, 2, 2.5)){
    cmp.object <- FindClusters(cmp.object, resolution = x)
saveRDS(cmp.object, file = paste0(projectName, "_dim", ndims, ".RDS"))
}
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8508
Number of communities: 9
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8026
Number of communities: 18
Elapsed time: 2 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7700
Number of communities: 22
Elapsed time: 2 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7461
Number of communities: 28
Elapsed time: 2 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 12059
Number of edges: 424091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7257
Number of communities: 33
Elapsed time: 1 seconds

Clustree

what’s the max resolution we can achieve while keepign clusters stable?

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        plot.title <- paste0(projectName, "dim", ndims, "res", gsub("RNA_snn_res", "", meta.col))
        myplot <- DimPlot(cmp.object, 
                                            group.by = meta.col,
                                            reduction = "umap", 
                                            cols = color.palette
                                            ) + 
            ggtitle(plot.title)
        plot(myplot)
        png(filename = paste0(plot.title, ".png"), height = 800, width = 800)
        plot(DimPlot(cmp.object, 
                                            group.by = meta.col,
                                            reduction = "umap", 
                                            cols = color.palette, 
                                            pt.size = 1.5
                                            ) + 
            ggtitle(plot.title)
            )
        dev.off()
    }
}

for each resolution, number/percentage of cells in each cluster?

tot.cells <- nrow(cmp.object@meta.data)
for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        stats.df <- data.frame(matrix(ncol = 2, nrow = length(new.clusters)))
        colnames(stats.df) <- c("num_cells", "pct_pop")
        rownames(stats.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(stats.df)){
                num.x <- nrow(meta.df[meta.df[meta.col] == row.id,])
                pct.x <- as.integer(num.x / tot.cells *100)
                # print(pct.x)
                stats.df[row.id, "num_cells"] <- num.x
                stats.df[row.id, "pct_pop"] <- pct.x
        }
        print(stats.df)
    }
}

Identify variable genes for new biomark

tot.cells <- nrow(cmp.object@meta.data)
for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        stats.df <- data.frame(matrix(ncol = 2, nrow = length(new.clusters)))
        colnames(stats.df) <- c("num_cells", "pct_pop")
        rownames(stats.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(stats.df)){
                num.x <- nrow(meta.df[meta.df[meta.col] == row.id,])
                pct.x <- as.integer(num.x / tot.cells *100)
                # print(pct.x)
                stats.df[row.id, "num_cells"] <- num.x
                stats.df[row.id, "pct_pop"] <- pct.x
        }
        print(stats.df)
    }
}

Gene profiles of clusters

set ident at res = 1 and get markers

Idents(cmp.object) <- "RNA_snn_res.1"
cmp.allmarkers.res1 <- FindAllMarkers(cmp.object)
cmp.top100markers.res1 <- cmp.allmarkers.res1 %>% group_by(cluster) %>% top_n(n = 100, wt = abs(avg_log2FC))

Find top.var genes in cmp.top100markers.res1

top.var <- cmp.object@assays$RNA@var.features[1:150]
# top.var
n.vargenes <- c()
for(gene in top.var){
    if(gene %in% cmp.top100markers.res1$gene){
        n.vargenes <- c(n.vargenes, gene)
    }
}
print(length(n.vargenes))
top.var[!(top.var %in% n.vargenes)]

Lets try to export these, with genes on rows and clusters on columns, and xpression value in data table

var.df <- cmp.top100markers.res1[cmp.top100markers.res1$gene %in% n.vargenes,]
var.df <- subset.data.frame(var.df, select = c("gene", "cluster", "avg_log2FC"))
var.df <- reshape2::dcast(var.df, gene~cluster, value.var = "avg_log2FC")
xlsx::write.xlsx(var.df, file = paste0(projectName, "_dim", ndims, "_candididateBiomarkGenes.xlsx"), sheetName = "res1", append = TRUE, row.names = FALSE)

Here’s the list of genes, plus some controls

res1.biomark.genes <- c("Aif1",
"Aqp1",
"Birc5",
"Ccl3",
"Ccr2",
"Cd74",
"Cdc20",
"Cenpf",
"Cst3",
"Ctsh",
"Dntt",
"Elane",
"Ermap",
"F13a1",
"Fcer1g",
"Gm15915",
"Gm17590",
"H2-Aa",
"H2-Eb1",
"H2afx",
"H2afy",
"Hist1h2ac",
"Hmgb2",
"Hp",
"Ighm",
"Irf8",
"Lgals3",
"Lmo4",
"Ms4a2",
"Mt1",
"Plac8",
"Prtn3",
"Rap1b",
"Rgs1",
"Vwf",
"Wfdc17",
"Csrp3",
"Hist1h2ae",
"Ifitm1",
"Lgals1",
"Tmsb4x",
"Arl6ip1",
"Car2",
"Ccl9",
"Ccnb2",
"Cd9",
"Cenpa",
"Cpa3",
"Fos",
"Hist1h2ap",
"Ly6c2",
"Mpo",
"Pclaf",
"Slpi",
"Top2a",
"Ube2c",
"Ly86",
"Hist1h2bc",
"Pf4",
"Apoe",
"Ctsg",
"Car1",
"Hmmr", 
"Gapdh", 
"B2m", 
"Actb", 
"Hprt1",
"Gusb")

make vln plots per cluster

res1.biomark.genes <- c("Aif1",
"Aqp1",
"Birc5",
"Ccl3",
"Ccr2",
"Cd74",
"Cdc20",
"Cenpf",
"Cst3",
"Ctsh",
"Dntt",
"Elane",
"Ermap",
"F13a1",
"Fcer1g",
"Gm15915",
"Gm17590",
"H2-Aa",
"H2-Eb1",
"H2afx",
"H2afy",
"Hist1h2ac",
"Hmgb2",
"Hp",
"Ighm",
"Irf8",
"Lgals3",
"Lmo4",
"Ms4a2",
"Mt1",
"Plac8",
"Prtn3",
"Rap1b",
"Rgs1",
"Vwf",
"Wfdc17",
"Csrp3",
"Hist1h2ae",
"Ifitm1",
"Lgals1",
"Tmsb4x",
"Arl6ip1",
"Car2",
"Ccl9",
"Ccnb2",
"Cd9",
"Cenpa",
"Cpa3",
"Fos",
"Hist1h2ap",
"Ly6c2",
"Mpo",
"Pclaf",
"Slpi",
"Top2a",
"Ube2c",
"Ly86",
"Hist1h2bc",
"Pf4",
"Apoe",
"Ctsg",
"Car1",
"Hmmr", 
"Gapdh", 
"B2m", 
"Actb", 
"Hprt1",
"Gusb")

Res 1.5

repeat for top.var genes in cmp.top100markers.res1.5

for(gene in res1.biomark.genes){
    plot.title <- paste0(projectName, "dim", ndims, "res1_", gene)
    myplot<- VlnPlot(cmp.object, features = gene, pt.size = 0.01) + ggtitle(plot.title)
    png(filename = paste0(plot.title, ".png"), height = 800, width = 1600)
    plot(myplot)
    dev.off()
    
}
Error in FetchData(object = object, vars = features, slot = slot) : 
  None of the requested variables were found: Hprt1

Lets try to export these, with genes on rows and clusters on columns, and xpression value in data table

var.df <- cmp.top100markers.res1.5[cmp.top100markers.res1.5$gene %in% n.vargenes,]
var.df <- subset.data.frame(var.df, select = c("gene", "cluster", "avg_log2FC"))
var.df <- reshape2::dcast(var.df, gene~cluster)
xlsx::write.xlsx(var.df, file = paste0(projectName, "_dim", ndims, "_candididateBiomarkGenes.xlsx"), sheetName = "res1.5", append = TRUE, row.names = FALSE)

For each resolution, what percentage of cells in each cluster are enriched for one of our clust.IDs?

Test: what percentage of each new clusterID matches one of the older clusters?

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        enrich.df <- data.frame(matrix(ncol = 4, nrow = length(new.clusters)))
        colnames(enrich.df) <- c(3, 17, 10, 11)
        rownames(enrich.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(enrich.df)){
            tot.clus <- nrow(meta.df[meta.df[[meta.col]] == row.id,])
            for(col.id in colnames(enrich.df)){
                num.x <- nrow(meta.df[(meta.df[[meta.col]] == row.id) & (meta.df$clust.ID == col.id),])
                pct.x <- as.integer(num.x / tot.clus *100)
                # print(pct.x)
                enrich.df[row.id, col.id] <- pct.x
            }
        }
        colnames(enrich.df) <- sapply(colnames(enrich.df), function(x) paste0("oldcluster", x))
        rownames(enrich.df) <- sapply(rownames(enrich.df), function(x) paste0("newcluster", x))
        xlsx::write.xlsx(enrich.df, file = paste0("PctOfNewClustersOverlappingOldClusters_", projectName, "_dim", ndims, ".xlsx"), sheetName = paste0(gsub("RNA_snn_", "", meta.col)), append = TRUE)
        print(enrich.df)
    }
}

Absolutely terrible overlap, no enrichment of any of these across the new clustering algorithm. Maybe should try 95% variation covered

Find old cells on UMAP

time for the super scarey moment to see if the cells from seuratv1 still cluster together on in seurat v4

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        enrich.df <- data.frame(matrix(ncol = 4, nrow = length(new.clusters)))
        colnames(enrich.df) <- c(3, 17, 10, 11)
        rownames(enrich.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(enrich.df)){
            tot.clus <- nrow(meta.df[meta.df[[meta.col]] == row.id,])
            for(col.id in colnames(enrich.df)){
                num.x <- nrow(meta.df[(meta.df[[meta.col]] == row.id) & (meta.df$clust.ID == col.id),])
                pct.x <- as.integer(num.x / tot.clus *100)
                # print(pct.x)
                enrich.df[row.id, col.id] <- pct.x
            }
        }
        colnames(enrich.df) <- sapply(colnames(enrich.df), function(x) paste0("oldcluster", x))
        rownames(enrich.df) <- sapply(rownames(enrich.df), function(x) paste0("newcluster", x))
        xlsx::write.xlsx(enrich.df, file = paste0("PctOfNewClustersOverlappingOldClusters_", projectName, "_dim", ndims, ".xlsx"), sheetName = paste0(gsub("RNA_snn_", "", meta.col)), append = TRUE)
        print(enrich.df)
    }
}
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.poi.util.SAXHelper (file:/Users/heustonef/Library/R/4.0/library/xlsxjars/java/poi-ooxml-3.10.1-20140818.jar) to constructor com.sun.org.apache.xerces.internal.util.SecurityManager()
WARNING: Please consider reporting this to the maintainers of org.apache.poi.util.SAXHelper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
DimPlot(cmp.object,
                reduction = "umap",
                group.by = "clust.ID", 
                # split.by = "orig.ident",
                cols = c("gray", "orange", "blue", "red", "green"),)

Gene expression of old clustrs on new map

Let’s see if we can get some gene expression profiles on these…

DimPlot(cmp.object,
                reduction = "umap",
                group.by = "orig.ident", 
                split.by = "clust.ID",
                cols = c("gray", "orange", "blue", "red", "green"),)

Total var 80%

Neighborhood and umap

set total.var <- 80%

gene.list <- c("Gata1", "Gata2", "Pf4", "Dntt", "Mpo", "Meis1", "Irf8", "Elane", "Fli1", "Zfpm1")
VlnPlot(cmp.object, features = gene.list, group.by = "clust.ID", pt.size = 0.01, cols = c("gray", "orange", "blue", "red", "green"))

Plot UMAP

for(x in c(0.5, 1, 1.5, 2, 2.5)){
    cmp.object <- FindClusters(cmp.object, resolution = x)
saveRDS(cmp.object, file = paste0(projectName, "_dim", ndims, ".RDS"))
}
for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        myplot <- DimPlot(cmp.object, 
                                            group.by = meta.col,
                                            reduction = "umap", 
                                            cols = color.palette
                                            ) + 
            ggtitle(paste0(projectName, " dim", ndims, "res", gsub("RNA_snn_res", "", meta.col) ))
        plot(myplot)
    }
}

Clustree

what’s the max resolution we can achieve while keepign clusters stable?

plot.title <- paste0(projectName, "_clustree_ndim", max(cmp.object@commands$RunUMAP.RNA.pca$dims))
my.clustree <- clustree(cmp.object, prefix = "RNA_snn_res.", node_colour = "sc3_stability", exprs = "scale.data") + 
    scale_color_continuous(low = 'red3', high = 'white') + 
    ggtitle(plot.title)
png(filename = paste0(plot.title, ".png"), height = 800, width = 1600)
plot(my.clustree)
dev.off()

for each resolution, number/percentage of cells in each cluster?

tot.cells <- nrow(cmp.object@meta.data)
for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        stats.df <- data.frame(matrix(ncol = 2, nrow = length(new.clusters)))
        colnames(stats.df) <- c("num_cells", "pct_pop")
        rownames(stats.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(stats.df)){
                num.x <- nrow(meta.df[meta.df[meta.col] == row.id,])
                pct.x <- as.integer(num.x / tot.cells *100)
                # print(pct.x)
                stats.df[row.id, "num_cells"] <- num.x
                stats.df[row.id, "pct_pop"] <- pct.x
        }
        print(stats.df)
    }
}

For each resolution, what percentage of cells in each cluster are enriched for one of our clust.IDs?

Test: what percentage of each new clusterID matches one of the older clusters?

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        enrich.df <- data.frame(matrix(ncol = 4, nrow = length(new.clusters)))
        colnames(enrich.df) <- c(3, 17, 10, 11)
        rownames(enrich.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(enrich.df)){
            tot.clus <- nrow(meta.df[meta.df[[meta.col]] == row.id,])
            for(col.id in colnames(enrich.df)){
                num.x <- nrow(meta.df[(meta.df[[meta.col]] == row.id) & (meta.df$clust.ID == col.id),])
                pct.x <- as.integer(num.x / tot.clus *100)
                # print(pct.x)
                enrich.df[row.id, col.id] <- pct.x
            }
        }
        colnames(enrich.df) <- sapply(colnames(enrich.df), function(x) paste0("oldcluster", x))
        rownames(enrich.df) <- sapply(rownames(enrich.df), function(x) paste0("newcluster", x))
        xlsx::write.xlsx(enrich.df, file = paste0("PctOfNewClustersOverlappingOldClusters_", projectName, "_dim", ndims, ".xlsx"), sheetName = paste0(gsub("RNA_snn_", "", meta.col)), append = TRUE)
        print(enrich.df)
    }
}

Absolutely terrible overlap, no enrichment of any of these across the new clustering algorithm. Maybe should try 95% variation covered

Find old cells on UMAP

time for the super scarey moment to see if the cells from seuratv1 still cluster together on in seurat v4

DimPlot(cmp.object,
                reduction = "umap",
                group.by = "clust.ID", 
                # split.by = "orig.ident",
                cols = c("gray", "orange", "blue", "red", "green"),)
DimPlot(cmp.object,
                reduction = "umap",
                group.by = "orig.ident", 
                split.by = "clust.ID",
                cols = c("gray", "orange", "blue", "red", "green"),)

Total var 95%

Neighborhood and umap

set total.var <- 95%

tot.var <- percent.variance(cmp.object@reductions$pca@stdev, plot.var = FALSE, return.val = TRUE)
ndims <- length(which(cumsum(tot.var) <= 95))

cmp.object <- FindNeighbors(cmp.object, dims = 1:ndims)
cmp.object <- FindClusters(cmp.object, resolution = 0.5)
cmp.object <- RunUMAP(cmp.object, dims = 1: ndims)

Plot UMAP

for(x in c(0.5, 1, 1.5, 2, 2.5)){
    cmp.object <- FindClusters(cmp.object, resolution = x)
}
saveRDS(cmp.object, file = paste0(projectName, "_dim", ndims, ".RDS"))
cmp.object <- readRDS("CMP_dim41.RDS")
plot.title <- paste0(projectName, "_clustree_ndim", max(cmp.object@commands$RunUMAP.RNA.pca$dims))
my.clustree <- clustree(cmp.object, prefix = "RNA_snn_res.", node_colour = "sc3_stability", exprs = "scale.data") + 
    scale_color_continuous(low = 'red3', high = 'white') + 
    ggtitle(plot.title)
png(filename = paste0(plot.title, ".png"), height = 800, width = 1600)
plot(my.clustree)
dev.off()

For each resolution, what percentage of cells in each cluster are enriched for one of our clust.IDs?

Test: what percentage of each new clusterID matches one of the older clusters?

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        new.clusters <- sort(as.numeric(levels(cmp.object@meta.data[[meta.col]])))
        enrich.df <- data.frame(matrix(ncol = 4, nrow = length(new.clusters)))
        colnames(enrich.df) <- c(3, 17, 10, 11)
        rownames(enrich.df) <- new.clusters
        meta.df <- cmp.object@meta.data
        for(row.id in rownames(enrich.df)){
            tot.clus <- nrow(meta.df[meta.df[[meta.col]] == row.id,])
            for(col.id in colnames(enrich.df)){
                num.x <- nrow(meta.df[(meta.df[[meta.col]] == row.id) & (meta.df$clust.ID == col.id),])
                pct.x <- as.integer(num.x / tot.clus *100)
                # print(pct.x)
                enrich.df[row.id, col.id] <- pct.x
            }
        }
        colnames(enrich.df) <- sapply(colnames(enrich.df), function(x) paste0("oldcluster", x))
        rownames(enrich.df) <- sapply(rownames(enrich.df), function(x) paste0("newcluster", x))
        xlsx::write.xlsx(enrich.df, file = paste0("PctOfNewClustersOverlappingOldClusters_", projectName, "_dim", ndims, ".xlsx"), sheetName = paste0(gsub("RNA_snn_", "", meta.col)), append = TRUE)
        print(enrich.df)
    }
}

Absolutely terrible overlap, no enrichment of any of these across the new clustering algorithm. Maybe should try 95% variation covered

Find old cells on UMAP

time for the super scarey moment to see if the cells from seuratv1 still cluster together on in seurat v4

DimPlot(cmp.object,
                reduction = "umap",
                group.by = "clust.ID", 
                pt.size = .1,
                # split.by = "orig.ident",
                cols = c("gray", "orange", "blue", "red", "green"),)
DimPlot(cmp.object,
                reduction = "umap",
                group.by = "orig.ident", 
                split.by = "clust.ID",
                cols = c("gray", "orange", "blue", "red", "green"),)

Gene expression of old clustrs on new map

Let’s see if we can get some gene expression profiles on these…

gene.list <- c("Gata1", "Gata2", "Pf4", "Dntt", "Mpo", "Meis1", "Irf8", "Elane", "Fli1", "Zfpm1")
VlnPlot(cmp.object, features = gene.list, group.by = "clust.ID", pt.size = 0.01, cols = c("gray", "orange", "blue", "red", "green"))

Used the exce doc to do some fancy conditional formatting. Old cluster 17 is pretty dispersed until you it resolution 2.5. Otherise, cells in old cluster 17 do not constitute more than 40% of any cells in the new clusters.
As far as I can see, the two approaches are to do DGEof new CMP w/ resolution = 2.5, AND/OR do DGe using older cluster IDs. Sure seems to make sense to do both…

DGE w/ resolution = 2.5

Strt with comparing all clusters against all other clusters Write out cluster info

calculate FindAllMarkers() for different idents and save to new file

ident.list <- c("RNA_snn_res.0.5", "RNA_snn_res.1", "RNA_snn_res.1.5", "RNA_snn_res.2", "RNA_snn_res.2.5", "clust.ID")
for(tested.ident in ident.list){
    Idents(cmp.object) <- tested.ident
    all.markers <- FindAllMarkers(cmp.object)
    xlsx::write.xlsx(x = all.markers[,c("avg_log2FC", "p_val_adj", "cluster", "gene")], 
                                     file = paste0(projectName, "_FindALLMarkers_res2.5.xlsx"), 
                                     sheetName = tested.ident, 
                                     col.names = TRUE, 
                                     row.names = FALSE, 
                                     append = TRUE)
}

Create FindAllMarkers() lists for GSEA

Idents(cmp.object) <- "RNA_snn_res.2.5"
res.2.5.allmarkers <- FindAllMarkers(cmp.object)

Map HGNC symbols

Mouse2HumanTable <- Mouse2Human(res.2.5.allmarkers$gene)

HGNC <- with(Mouse2HumanTable, Mouse2HumanTable$HGNC[match(res.2.5.allmarkers$gene, Mouse2HumanTable$MGI)])
head(res.2.5.allmarkers)
res.2.5.allmarkers$HGNC <- HGNC
tail(res.2.5.allmarkers)
sig.res.2.5 <- res.2.5.allmarkers[res.2.5.allmarkers$p_val_adj <= 0.05, ]
sig.res.2.5 <- sig.res.2.5[c("avg_log2FC", "HGNC", "cluster")]
sig.res.2.5 <- sig.res.2.5[!(sig.res.2.5$HGNC == "" | is.na(sig.res.2.5$HGNC)),] # GSEA will fail if there are any blanks or NAs in the table
sig.res.2.5 <- sig.res.2.5[]
for(cluster in unique(sig.res.2.5$cluster)){
    print(paste("writing cluster", cluster))
    new.table <- sig.res.2.5[sig.res.2.5$cluster == cluster, c("HGNC", "avg_log2FC")]
    new.table <- new.table[order(-new.table$avg_log2FC), ]
    write.table(new.table, file = paste0("RankList_res2.5_findAll_hgnc/res.2.5cluster", cluster, ".rnk"), quote = FALSE, row.names = FALSE, col.names = TRUE, sep = "\t", )
    
}

calculate FindMarkers() that distinguish each cluster (might overlab between clusters)

ident.list <- c("RNA_snn_res.0.5", "RNA_snn_res.1", "RNA_snn_res.1.5", "RNA_snn_res.2", "RNA_snn_res.2.5", "clust.ID")
for(tested.ident in ident.list){
    object.copy <- cmp.object
    Idents(object.copy) <- tested.ident
    print(paste("testing", tested.ident))
    for (cluster in sort(as.numeric(levels(object.copy@meta.data[[tested.ident]])))){
        print(paste("looking at cluster", cluster))
        cluster.markers <- FindMarkers(object.copy, ident.1 = cluster)
        try(
            xlsx::write.xlsx(x = cluster.markers[,c("avg_log2FC", "p_val_adj")], 
                                             file = paste0(projectName, "_FindMarkers_", gsub("RNA_snn_", "", tested.ident), ".xlsx"), 
                                             sheetName = paste0("clst", cluster), 
                                             col.names = TRUE, 
                                             row.names = TRUE, 
                                             append = TRUE)
        )   
    }
    remove(object.copy)
}
for (cluster in sort(as.numeric(levels(cmp.object@meta.data$RNA_snn_res.2.5)))){
    cluster.markers <- FindMarkers(cmp.object, ident.1 = cluster)
    xlsx::write.xlsx(x = cluster.markers[,c("avg_log2FC", "p_val_adj")], 
                                     file = paste0(projectName, "_FindMarkers_res2.5.xlsx"), 
                                     sheetName = paste0("clst", cluster), 
                                     col.names = TRUE, 
                                     row.names = TRUE, 
                                     append = TRUE)
}

Combine clusters that might represent old cluster ids

DGE w/ metadata against clust.ID against “0”

reset ident as “clust.ID” and rerun FindAllMarkers()

    Idents(cmp.object) <- "clust.ID"
    all.markers <- FindAllMarkers(cmp.object)
    xlsx::write.xlsx(x = all.markers[,c("avg_log2FC", "p_val_adj", "cluster", "gene")], 
                                     file = paste0(projectName, "_FindALLMarkers_clustID.xlsx"), 
                                     sheetName = "clustID", 
                                     col.names = TRUE, 
                                     row.names = FALSE, 
                                     append = TRUE)
# Idents(cmp.object) <- "clust.ID"
for (cluster in unique(cmp.object@meta.data$clust.ID)){
    print(cluster)
    cluster.markers <- FindMarkers(cmp.object, ident.1 = cluster)
    xlsx::write.xlsx(x = cluster.markers[,c("avg_log2FC", "p_val_adj")], 
                                     file = paste0(projectName, "_FindMarkers_clustID.xlsx"), 
                                     sheetName = paste0("oldclust", cluster), 
                                     col.names = TRUE, 
                                     row.names = TRUE, 
                                     append = TRUE)
}

Distinguishing features of clusters

Previously defined biomark genes based on PC contributions. Original list was based on all msAggr, but let’s see how CMP subset does?

VizDimLoadings(cmp.object, dims = 1:10, nfeatures = 30, reduction = "pca", ncol = 2)
pca.df <- cmp.object[["pca"]]
pca.df <- as.data.frame(as.matrix(slot(object = pca.df, name = "feature.loadings")))
print(cmp.object[["pca"]], dims = 2, nfeatures = 5)
rownames(pca.df[pca.df$PC_2 %in% sort(pca.df$PC_2, decreasing = TRUE)[1:5], ])
rownames(pca.df[pca.df$PC_2 %in% sort(pca.df$PC_2)[1:5], ])

now we can get a list of principal components!
first pull the list of oldAnalysis CMP top PC genes

cmp.biomark <- read.table(file = "/Users/heustonef/Desktop/CMPSubpops/BioMark/ProbePanels/CMP_PCTopGenes.txt", sep = "\t", header = TRUE)
biomark.cmptargets <- c()
for(df.col in 1:ncol(cmp.biomark)){
    biomark.cmptargets <- c(biomark.cmptargets, biomark[,df.col])
}
print(colnames(biomark))
print(paste("total gene count:", length(biomark.cmptargets)))

Now get the list of current pc gene trgets (oldAnalysis used ndim = 1:6, so we’ll start with that range)

pc.list <- c("PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6")
pc.genes <- lapply(pc.list, function(x) rownames(pca.df[pca.df[[x]] %in% sort(pca.df[[x]], decreasing = TRUE)[1:30],])) #targeting roughly 180 genes like in biomark.cmptargets
pc.genes <- unique(unlist(pc.genes))
print(paste("total gene count:", length(pc.genes)))

Now compare the lists, I guess:

# setdiff(x,y) gives you things in x not in y. setdiff(y,x) gives you things in y not in x
setdiff(biomark.cmptargets, pc.genes)
# print(paste("\n length:", length(setdiff(biomark.cmptargets, pc.genes))))
writeLines(c("", "length:", length(setdiff(biomark.cmptargets, pc.genes))))

Umm, yeah that went kinda how I expected. Let’s do this again, but for the actual biomark gene lists.

biomark <- read.table(file = "/Users/heustonef/Desktop/CMPSubpops/BioMark/ProbePanels/BiomarkProbeList.txt", sep = "\t")
biomark <- biomark[,1]
setdiff(biomark, pc.genes)
writeLines(c("", "length:", length(setdiff(biomark, pc.genes))))

What if we increase the number of pcs but decrease the depth of each? This might cover more of biomark, which was originally developed using msAggr instead of only the CMP subset

pc.list <- c("PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6", "PC_7", "PC_8", "PC_9", "PC_10")
pc.genes <- lapply(pc.list, function(x) rownames(pca.df[pca.df[[x]] %in% sort(pca.df[[x]], decreasing = TRUE)[1:20],]))
pc.genes <- unique(unlist(pc.genes))
print(paste("total gene count:", length(pc.genes)))
setdiff(biomark, pc.genes)
writeLines(c("", "length:", length(setdiff(biomark, pc.genes))))

For comparison, let’s just see how many of biomark.cmptargets were actually included in biomark

setdiff(biomark.cmptargets, biomark)
writeLines(c("", "length:", length(setdiff(biomark.cmptargets, pc.genes))))
length(biomark) - length(setdiff(biomark, biomark.cmptargets))
length(biomark) - length(setdiff(biomark, pc.genes))

So when you look at it like that, it’s not actually that far off.

What are the similarities?:

setdiff(setdiff(biomark, biomark.cmptargets), setdiff(biomark, pc.genes))

These are genes from the 97probes not in the old CMP set that are also not in the new CMP set. Other than Itga2b (which is a failed probe anyway), nothing screams. Also we’d have thrown Flt3 and Cd34 for in anyway because they’re requisite cell surface markers (also Flt3 surface marker is expensive but otherwise not noteworthy and not used in the current sorting strategy)

What about cell surface marker expression? * Cd34 * Cd16/32 * Cd9 * Cd41 * Cd48 * Sca1 (just throw that in for sh*&s and giggles)

surface.markers <- c("Cd34", "Fcgr3", "Fcgr2b", "Cd9", "Itga2b", "Cd48", "Ly6a")
FeaturePlot(cmp.object, features = surface.markers, pt.size = 1, split.by = "clust.ID", ncol = 1)

Save as png

png(filename = "FeaturePlot_CMP_surfaceMarkers_clustIDfacet.png", height = 1600, width = 1600)
FeaturePlot(cmp.object, features = surface.markers, pt.size = 1, split.by = "clust.ID", ncol = 1)
dev.off()

Compare @g hierarchcial clusteirng

Do clustering using biomark RNAs as input

# Read in BiomarkRNAs
biomark.rnas <- read.table('/Users/heustonef/Desktop/10XGenomicsData/BiomarkRNAs.txt')
biomark.rnas <- biomark.rnas$V1

use biomark RNAs to define dimensional reduction

cmp.object <- readRDS("CMP_raw.RDS")
cmp.object <- RunPCA(cmp.object, features = biomark.rnas, ndims.print = 1:5, , nfeatures.print = 5)
ElbowPlot(cmp.object, ndims = 50)

Now run the clustering

tot.var <- percent.variance(cmp.object@reductions$pca@stdev, plot.var = FALSE, return.val = TRUE)
ndims <- length(which(cumsum(tot.var) <= 90))

cmp.object <- FindNeighbors(cmp.object, dims = 1:ndims)
cmp.object <- FindClusters(cmp.object, resolution = 0.5)
cmp.object <- RunUMAP(cmp.object, dims = 1: ndims)

find the clusters

for(x in c(0.5, 1, 1.5, 2, 2.5)){
    cmp.object <- FindClusters(cmp.object, resolution = x)
}

Plot the umaps and cell cluster ids

for (meta.col in colnames(cmp.object@meta.data)){
    if(grepl(pattern = ("RNA_snn_res"), x = meta.col)==TRUE){
        myplot <- DimPlot(cmp.object, 
                                            group.by = meta.col,
                                            reduction = "umap", 
                                            cols = color.palette
                                            ) + 
            ggtitle(paste0(projectName, " dim", ndims, "res", gsub("RNA_snn_res", "", meta.col) ))
        plot(myplot)
    }
}

Calculate anticipated number of cells you’ll find in each biomark cluster

Get # cells in each cluster

tot.cellcount <- nrow(cmp.object@meta.data)
res05.list <- sort(unique(cmp.object@meta.data$RNA_snn_res.0.5), decreasing = FALSE)
sapply(res05.list, 
             function(x){
                print(
                    paste(
                        "cluster", x, "=", 
                        nrow(cmp.object@meta.data[cmp.object@meta.data$RNA_snn_res.0.5 == x,]), 
                        "cells or", 
                        round(nrow(cmp.object@meta.data[cmp.object@meta.data$RNA_snn_res.0.5 == x,])/tot.cellcount*100, digits = 2), 
                        "% of total"
                    )
                )
             }
            )

So we did the dimensional reduction based on the biomark RNAs, then did our UMAP nearest neighbor clustering.

In the biomark hierarchcial clustering analysis I assayed 167 cells. The smallest cluster I detected had 3 cells, or 1.8% of total, and this is an uncomfortably small number of cells. Based on the UMAP calculations I would therefore expect to find 11 or 12 of the predicted 15 clusters. I found 12, and I don’t really like that last one, so 11 or 12. Since I did the hierarchcial clustering yesterday and did this math today, we can say it was independent of these results and therefore totally legit. Yay!!

LS0tCnRpdGxlOiAiQ01QU3Vic2V0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIFVwZGF0ZXMKCiMjIFVwZGF0ZSAyMDIxLjA4LjExCk1vc3QgdGhvcm91Z2ggd2F5IHRvIHJlYWRkcmVzcyBkaWZmZXJlbmNlcyBiZXR3ZWVuIG9yaWdpbmFsIGFuZCBjdXJyZW50IGFuYWx5c2VzIGlzIHRvIGpzdXQgcmVkbyB0aGUgYmlvbWFyay4gVG8gdGhhdCBlbmQsIHdpbGwgcmVzdGFydCBhbmFseXNpcyBvZiAqanVzdCogQ01QbTIsIGV4Y2x1ZGluZyBvdGhlciBkYXRhc2V0cyAoaS5lLiwgTFNLLCBNRVAsIEdNUCkuIFdpbGwgYWxzbyBrZWVwIAoKCiMgTm90ZWJvb2sgc2V0dXAKCkNyZWF0aW5nIG5ldyBwaXBlbGluZSB1c2luZyBzZXVyYXQgdjQuMC4yIGF2YWlsYWJsZSAyMDIxLjA2LjA4CgpMb2FkIGxpYnJhcmllcyByZXF1aXJlZCBmb3IgU2V1cmF0djQKCmBgYHtyIHNldHVwfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShjbHVzdHJlZSkKYGBgCgojIFNldCBnbG9iYWwgdmFyaWFibGVzCmBgYHtyfQpwcm9qZWN0TmFtZSA8LSAiQ01QIgpqYWNrc3RyYXcuZGltIDwtIDQwCmBgYAoKc3RvcmUgc2Vzc2lvbiBpbmZvCmBgYHtyfQpzZXNzaW9uSW5mby5maWxlbmFtZSA8LSBwYXN0ZTAocHJvamVjdE5hbWUsICJfc2Vzc2lvbkluZm8udHh0IikKc2luayhzZXNzaW9uSW5mby5maWxlbmFtZSkKc2Vzc2lvbkluZm8oKQpzaW5rKCkKYGBgCgoKYGBge3J9CnNvdXJjZSgiLi4vUkZ1bmN0aW9ucy9yZWFkXzEwWEdlbm9taWNzX2RhdGEuUiIpCnNvdXJjZSgiLi4vUkZ1bmN0aW9ucy9QZXJjZW50VmFyaWFuY2UuUiIpCnNvdXJjZSgiLi4vUkZ1bmN0aW9ucy9Nb3VzZTJIdW1hbl9pZGNvbnZlcnNpb24uUiIpCnNvdXJjZSAoIi4uL1JGdW5jdGlvbnMvQ29sb3JQYWxldHRlLlIiKQpgYGAKCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpzZXR3ZCgiLi4vLi4vY2VsbFJhbmdlci8iKSAjIHRlbXBvcmFyaWx5IGNoYW5naW5nIHdkIG9ubHkgd29ya3MgaWYgeW91IHJ1biB0aGUgZW50aXJlIGNodW5rIGF0IG9uY2UKZGF0YV9maWxlLmxpc3QgPC0gcmVhZF8xMFhHZW5vbWljc19kYXRhKHNhbXBsZS5saXN0ID0gIkNNUG0yIikKb2JqZWN0LmRhdGEgPC1SZWFkMTBYKGRhdGFfZmlsZS5saXN0KQpgYGAKCgoKYGBge3J9CmNtcC5vYmplY3Q8LSBDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gb2JqZWN0LmRhdGEsIG1pbi5jZWxscyA9IDMsIG1pbi5nZW5lcyA9IDIwMCwgcHJvamVjdCA9IHByb2plY3ROYW1lKQpgYGAKCkNsZWFuIHVwIHRvIGZyZWUgbWVtb3J5CgpgYGB7cn0KcmVtb3ZlKG9iamVjdC5kYXRhKQpgYGAKCgpBZGQgbWl0b2Nob25kcmlhbCBtZXRhZGF0YSBhbmQgcGxvdCBzb21lIGJhc2ljIGZlYXR1cmVzCmBgYHtyfQpjbXAub2JqZWN0W1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChjbXAub2JqZWN0LCBwYXR0ZXJuID0gIl5tdC0iKQpWbG5QbG90KGNtcC5vYmplY3QsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMywgcHQuc2l6ZSA9IDAsIGZpbGwuYnkgPSAnb3JpZy5pZGVudCcsICkKYGBgCgoKYGBge3J9CnBsb3QxIDwtIEZlYXR1cmVTY2F0dGVyKGNtcC5vYmplY3QsIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLCBmZWF0dXJlMiA9ICJwZXJjZW50Lm10IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIHB0LnNpemUgPSAwLjAxKQpwbG90MiA8LSBGZWF0dXJlU2NhdHRlcihjbXAub2JqZWN0LCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIHB0LnNpemUgPSAwLjAxKQpwbG90MSArIHBsb3QyCmBgYAojIyBGaWx0ZXIgZGF0YQpyZW1vdmUgbG93IHF1YWxpdHkgY2VsbHMKcmVxdWlyZTogbkZlYXR1cmVfUk5BIGJldHdlZW4gMjAwIGFuZCA0MDAwIChpbmNsdXNpdmUpCnJlcXVpcmU6IHBlcmNlbnQubXQgPD01CgpgYGB7cn0KcHJpbnQocGFzdGUoIm9yaWdpbmFsIG9iamVjdDoiLCBucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhKSwgImNlbGxzIiwgc2VwID0gIiAiKSkKY21wLm9iamVjdCA8LSBzdWJzZXQoY21wLm9iamVjdCwgCgkJCQkJCQkJCQkJCXN1YnNldCA9IG5GZWF0dXJlX1JOQSA+PTIwMCAmIAoJCQkJCQkJCQkJCQkJbkZlYXR1cmVfUk5BIDw9IDQwMDAgJiAKCQkJCQkJCQkJCQkJCXBlcmNlbnQubXQgPD0gNQoJCQkJCQkJCQkJCQkpCnByaW50KHBhc3RlKCJuZXcgb2JqZWN0OiIsIG5yb3coY21wLm9iamVjdEBtZXRhLmRhdGEpLCAiY2VsbHMiLCBzZXAgPSAiICIpKQpgYGAKCgoKYGBge3J9CmNtcC5vYmplY3QgPC0gTm9ybWFsaXplRGF0YShjbXAub2JqZWN0LCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKYGBgCgoKRmluZCB2YXJpYWJsZSBmZWF0dXJlcwpgYGB7ciBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gMn0KY21wLm9iamVjdCA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhjbXAub2JqZWN0LCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDApCnRvcDEwIDwtIGhlYWQoVmFyaWFibGVGZWF0dXJlcyhjbXAub2JqZWN0KSwgMTApCnBsb3QxIDwtIFZhcmlhYmxlRmVhdHVyZVBsb3QoY21wLm9iamVjdCkKcGxvdDIgPC0gTGFiZWxQb2ludHMocGxvdCA9IHBsb3QxLCBwb2ludHMgPSB0b3AxMCwgcmVwZWwgPSBUUlVFKQpwbG90MSArIHBsb3QyCmBgYAoKIyMgU2NhbGUgZGF0YSAobGluZWFyIHRyYW5zZm9ybWF0aW9uKQpXZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IGNvbXBhcmluZyBsaWJyYXJ5IGRlcHRocywgc28gd2UnbGwganVzdCBkbyBub3JtYWxpemF0aW9uL1NjYWxlIGRhdGEKCmBgYHtyIGVjaG8gPSBGQUxTRX0KYWxsLmdlbmVzIDwtIHJvd25hbWVzKGNtcC5vYmplY3QpCmNtcC5vYmplY3QgPC0gU2NhbGVEYXRhKGNtcC5vYmplY3QsIGZlYXR1cmVzID0gYWxsLmdlbmVzLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIpKQpgYGAKCiMjIFNhdmUgcmF3IG9iamVjdApgYGB7cn0Kc2F2ZVJEUyhjbXAub2JqZWN0LCBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX3Jhdy5SRFMiKSkKYGBgCgoKCmBgYHtyfQpjbXAub2JqZWN0IDwtIFJ1blBDQShjbXAub2JqZWN0LCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoY21wLm9iamVjdCksIG5kaW1zLnByaW50ID0gMTo1LCBuZmVhdHVyZXMucHJpbnQgPSA1KQpgYGAKCmBgYHtyfQpEaW1QbG90KGNtcC5vYmplY3QsIHJlZHVjdGlvbiA9ICJwY2EiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKVml6RGltTG9hZGluZ3MoY21wLm9iamVjdCwgZGltcyA9IDE6NiwgbmZlYXR1cmVzID0gMTAsIHJlZHVjdGlvbiA9ICJwY2EiLCBuY29sID0gMykKCmBgYAoKQ2FsY3VsYXRlIGRpbWVuc2lvbmFsaXR5CmBgYHtyLCBmaWd1cmVzLXNpZGUsIGZpZy5zaG93PSdob2xkJywgb3V0LndpZHRoPSI1MCUifQpFbGJvd1Bsb3QoY21wLm9iamVjdCwgbmRpbXMgPSA1MCkKcGVyY2VudC52YXJpYW5jZShjbXAub2JqZWN0QHJlZHVjdGlvbnMkcGNhQHN0ZGV2KQpgYGAKTnVtYmVyIG9mIFBDcyBkZXNjcmliaW5nIFglIG9mIHZhcmlhbmNlCgpgYGB7cn0KdG90LnZhciA8LSBwZXJjZW50LnZhcmlhbmNlKGNtcC5vYmplY3RAcmVkdWN0aW9ucyRwY2FAc3RkZXYsIHBsb3QudmFyID0gRkFMU0UsIHJldHVybi52YWwgPSBUUlVFKQpwYXN0ZTAoIk51bSBwY3MgZm9yIDgwJSB2YXJpYW5jZToiLCBsZW5ndGgod2hpY2goY3Vtc3VtKHRvdC52YXIpIDw9IDgwKSkpCnBhc3RlMCgiTnVtIHBjcyBmb3IgODUlIHZhcmlhbmNlOiIsIGxlbmd0aCh3aGljaChjdW1zdW0odG90LnZhcikgPD0gODUpKSkKcGFzdGUwKCJOdW0gcGNzIGZvciA5MCUgdmFyaWFuY2U6IiwgbGVuZ3RoKHdoaWNoKGN1bXN1bSh0b3QudmFyKSA8PSA5MCkpKQpwYXN0ZTAoIk51bSBwY3MgZm9yIDk1JSB2YXJpYW5jZToiLCBsZW5ndGgod2hpY2goY3Vtc3VtKHRvdC52YXIpIDw9IDk1KSkpCgpgYGAKCiMgQWRkIGNsdXN0ZXIgSURzIGZyb20gU2V1cmF0IHYxCgpFeHBvcnRlZCBjZWxsIElEcyBmb3IgY2x1c3RlcnMgMywgMTcsIDEwLCAxMSBmcm9tIFNldXJhdCB2MS4gV2lsbCBhZGQgdGhlc2UgSURzIGFzIGEgbWV0YWRhdGEgY29sdW1uLiAgCkNyZWF0ZSBjb2x1bW4gImNsdXN0LklEIiBhbmQgcG9wdWxhdGUgd2l0aCAwJ3MuIFRoZW4gaW1wb3J0IElEcyBmb3IgY2x1c3RlcnMKCgoKYGBge3J9CmNsdXN0My5jZWxscyA8LSByZWFkLnRhYmxlKGZpbGUgPSAiLi4vU2V1cmF0djFfY2x1c3RlckNlbGxJRHMvY2x1c3RlcjNjZWxsSURzLnR4dCIsIGNvbC5uYW1lcyA9ICJjbHVzdDAzIikKY2x1c3QzLmNlbGxzIDwtIHNhcHBseShjbHVzdDMuY2VsbHMsIGZ1bmN0aW9uKHgpIHBhc3RlMChnc3ViKCJDTVAiLCAiQ01QbTIiLCB4KSwgIi0xIikpCmNsdXN0MTcuY2VsbHMgPC0gcmVhZC50YWJsZShmaWxlID0gIi4uL1NldXJhdHYxX2NsdXN0ZXJDZWxsSURzL2NsdXN0ZXIxN2NlbGxJRHMudHh0IiwgY29sLm5hbWVzID0gImNsdXN0MTciKQpjbHVzdDE3LmNlbGxzIDwtIHNhcHBseShjbHVzdDE3LmNlbGxzLCBmdW5jdGlvbih4KSBwYXN0ZTAoZ3N1YigiQ01QIiwgIkNNUG0yIiwgeCksICItMSIpKQpjbHVzdDEwLmNlbGxzIDwtIHJlYWQudGFibGUoZmlsZSA9ICIuLi9TZXVyYXR2MV9jbHVzdGVyQ2VsbElEcy9jbHVzdGVyMTBjZWxsSURzLnR4dCIsIGNvbC5uYW1lcyA9ICJjbHVzdDEwIikKY2x1c3QxMC5jZWxscyA8LSBzYXBwbHkoY2x1c3QxMC5jZWxscywgZnVuY3Rpb24oeCkgcGFzdGUwKGdzdWIoIkNNUCIsICJDTVBtMiIsIHgpLCAiLTEiKSkKY2x1c3QxMS5jZWxscyA8LSByZWFkLnRhYmxlKGZpbGUgPSAiLi4vU2V1cmF0djFfY2x1c3RlckNlbGxJRHMvY2x1c3RlcjExY2VsbElEcy50eHQiLCBjb2wubmFtZXMgPSAiY2x1c3QxMSIpCmNsdXN0MTEuY2VsbHMgPC0gc2FwcGx5KGNsdXN0MTEuY2VsbHMsIGZ1bmN0aW9uKHgpIHBhc3RlMChnc3ViKCJDTVAiLCAiQ01QbTIiLCB4KSwgIi0xIikpCmBgYAoKQWRkIG5ldyBtZXRhZGF0YSBjb2x1bW4KYGBge3J9CmNtcC5vYmplY3RAbWV0YS5kYXRhWydjbHVzdC5JRCddIDwtIDAKaGVhZChjbXAub2JqZWN0QG1ldGEuZGF0YSkKYGBgCgpub3cgbWFwIG5ldyBpZHMKYGBge3J9CmNtcC5vYmplY3RAbWV0YS5kYXRhJGNsdXN0LklEW3Jvd25hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSAlaW4lIGNsdXN0My5jZWxsc10gPC0gMwpjbXAub2JqZWN0QG1ldGEuZGF0YSRjbHVzdC5JRFtyb3duYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkgJWluJSBjbHVzdDE3LmNlbGxzXSA8LSAxNwpjbXAub2JqZWN0QG1ldGEuZGF0YSRjbHVzdC5JRFtyb3duYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkgJWluJSBjbHVzdDEwLmNlbGxzXSA8LSAxMApjbXAub2JqZWN0QG1ldGEuZGF0YSRjbHVzdC5JRFtyb3duYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkgJWluJSBjbHVzdDExLmNlbGxzXSA8LSAxMQpgYGAKCmRvIG51bWJlcnMgbWFrZSBzZW5zZT8KYGBge3J9Cm5yb3coY21wLm9iamVjdEBtZXRhLmRhdGFbY21wLm9iamVjdEBtZXRhLmRhdGEkY2x1c3QuSUQgPT0gMTAsXSkKbnJvdyhjbXAub2JqZWN0QG1ldGEuZGF0YVtjbXAub2JqZWN0QG1ldGEuZGF0YSRjbHVzdC5JRCA9PSAxMSxdKQpucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhW2NtcC5vYmplY3RAbWV0YS5kYXRhJGNsdXN0LklEID09IDE3LF0pCm5yb3coY21wLm9iamVjdEBtZXRhLmRhdGFbY21wLm9iamVjdEBtZXRhLmRhdGEkY2x1c3QuSUQgPT0gMyxdKQpgYGAKCgoKCgoKCgojIFRvdGFsIHZhciA5MCUKIyMgTmVpZ2hib3Job29kIGFuZCB1bWFwCnNldCB0b3RhbC52YXIgPC0gOTAlCmBgYHtyfQp0b3QudmFyIDwtIHBlcmNlbnQudmFyaWFuY2UoY21wLm9iamVjdEByZWR1Y3Rpb25zJHBjYUBzdGRldiwgcGxvdC52YXIgPSBGQUxTRSwgcmV0dXJuLnZhbCA9IFRSVUUpCm5kaW1zIDwtIGxlbmd0aCh3aGljaChjdW1zdW0odG90LnZhcikgPD0gOTApKQoKY21wLm9iamVjdCA8LSBGaW5kTmVpZ2hib3JzKGNtcC5vYmplY3QsIGRpbXMgPSAxOm5kaW1zKQpjbXAub2JqZWN0IDwtIEZpbmRDbHVzdGVycyhjbXAub2JqZWN0LCByZXNvbHV0aW9uID0gMC41KQpjbXAub2JqZWN0IDwtIFJ1blVNQVAoY21wLm9iamVjdCwgZGltcyA9IDE6IG5kaW1zKQoKYGBgClBsb3QgVU1BUAoKYGBge3J9CmZvcih4IGluIGMoMC41LCAxLCAxLjUsIDIsIDIuNSkpewoJY21wLm9iamVjdCA8LSBGaW5kQ2x1c3RlcnMoY21wLm9iamVjdCwgcmVzb2x1dGlvbiA9IHgpCn0Kc2F2ZVJEUyhjbXAub2JqZWN0LCBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX2RpbSIsIG5kaW1zLCAiLlJEUyIpKQpgYGAKCmBgYHtyfQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQlteXBsb3QgPC0gRGltUGxvdChjbXAub2JqZWN0LCAKCQkJCQkJCQkJCQlncm91cC5ieSA9IG1ldGEuY29sLAoJCQkJCQkJCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwgCgkJCQkJCQkJCQkJY29scyA9IGNvbG9yLnBhbGV0dGUKCQkJCQkJCQkJCQkpICsgCgkJCWdndGl0bGUocGFzdGUwKHByb2plY3ROYW1lLCAiIGRpbSIsIG5kaW1zLCAicmVzIiwgZ3N1YigiUk5BX3Nubl9yZXMiLCAiIiwgbWV0YS5jb2wpICkpCgkJcGxvdChteXBsb3QpCgl9Cn0KYGBgCgojIyMgQ2x1c3RyZWUKd2hhdCdzIHRoZSBtYXggcmVzb2x1dGlvbiB3ZSBjYW4gYWNoaWV2ZSB3aGlsZSBrZWVwaWduIGNsdXN0ZXJzIHN0YWJsZT8KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA1fQpwbG90LnRpdGxlIDwtIHBhc3RlMChwcm9qZWN0TmFtZSwgIl9jbHVzdHJlZV9uZGltIiwgbWF4KGNtcC5vYmplY3RAY29tbWFuZHMkUnVuVU1BUC5STkEucGNhJGRpbXMpKQpteS5jbHVzdHJlZSA8LSBjbHVzdHJlZShjbXAub2JqZWN0LCBwcmVmaXggPSAiUk5BX3Nubl9yZXMuIiwgbm9kZV9jb2xvdXIgPSAic2MzX3N0YWJpbGl0eSIsIGV4cHJzID0gInNjYWxlLmRhdGEiKSArIAoJc2NhbGVfY29sb3JfY29udGludW91cyhsb3cgPSAncmVkMycsIGhpZ2ggPSAnd2hpdGUnKSArIAoJZ2d0aXRsZShwbG90LnRpdGxlKQpwbmcoZmlsZW5hbWUgPSBwYXN0ZTAocGxvdC50aXRsZSwgIi5wbmciKSwgaGVpZ2h0ID0gODAwLCB3aWR0aCA9IDE2MDApCnBsb3QobXkuY2x1c3RyZWUpCmRldi5vZmYoKQoKYGBgCkkgdGhpbmsgSSdtIGxpa2luZyByZXMuMS4wIGZyb20gdGhpcy4gQWx0aG91Z2ggaG93IG11Y2ggZG9lcyB0aGlzIGNoYW5nZSBpZiBJIHVzZSBmZXdlciBQQ3MuLi4KCgoKZm9yIGVhY2ggcmVzb2x1dGlvbiwgbnVtYmVyL3BlcmNlbnRhZ2Ugb2YgY2VsbHMgaW4gZWFjaCBjbHVzdGVyPwoKYGBge3J9CnRvdC5jZWxscyA8LSBucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhKQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQluZXcuY2x1c3RlcnMgPC0gc29ydChhcy5udW1lcmljKGxldmVscyhjbXAub2JqZWN0QG1ldGEuZGF0YVtbbWV0YS5jb2xdXSkpKQoJCXN0YXRzLmRmIDwtIGRhdGEuZnJhbWUobWF0cml4KG5jb2wgPSAyLCBucm93ID0gbGVuZ3RoKG5ldy5jbHVzdGVycykpKQoJCWNvbG5hbWVzKHN0YXRzLmRmKSA8LSBjKCJudW1fY2VsbHMiLCAicGN0X3BvcCIpCgkJcm93bmFtZXMoc3RhdHMuZGYpIDwtIG5ldy5jbHVzdGVycwoJCW1ldGEuZGYgPC0gY21wLm9iamVjdEBtZXRhLmRhdGEKCQlmb3Iocm93LmlkIGluIHJvd25hbWVzKHN0YXRzLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbbWV0YS5kZlttZXRhLmNvbF0gPT0gcm93LmlkLF0pCgkJCQlwY3QueCA8LSBhcy5pbnRlZ2VyKG51bS54IC8gdG90LmNlbGxzICoxMDApCgkJCQkjIHByaW50KHBjdC54KQoJCQkJc3RhdHMuZGZbcm93LmlkLCAibnVtX2NlbGxzIl0gPC0gbnVtLngKCQkJCXN0YXRzLmRmW3Jvdy5pZCwgInBjdF9wb3AiXSA8LSBwY3QueAoJCX0KCQlwcmludChzdGF0cy5kZikKCX0KfQpgYGAKCgoKRm9yIGVhY2ggcmVzb2x1dGlvbiwgd2hhdCBwZXJjZW50YWdlIG9mIGNlbGxzIGluIGVhY2ggY2x1c3RlciBhcmUgZW5yaWNoZWQgZm9yIG9uZSBvZiBvdXIgY2x1c3QuSURzPwoKClRlc3Q6IHdoYXQgcGVyY2VudGFnZSBvZiBlYWNoIG5ldyBjbHVzdGVySUQgbWF0Y2hlcyBvbmUgb2YgdGhlIG9sZGVyIGNsdXN0ZXJzPwpgYGB7cn0KZm9yIChtZXRhLmNvbCBpbiBjb2xuYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkpewoJaWYoZ3JlcGwocGF0dGVybiA9ICgiUk5BX3Nubl9yZXMiKSwgeCA9IG1ldGEuY29sKT09VFJVRSl7CgkJbmV3LmNsdXN0ZXJzIDwtIHNvcnQoYXMubnVtZXJpYyhsZXZlbHMoY21wLm9iamVjdEBtZXRhLmRhdGFbW21ldGEuY29sXV0pKSkKCQllbnJpY2guZGYgPC0gZGF0YS5mcmFtZShtYXRyaXgobmNvbCA9IDQsIG5yb3cgPSBsZW5ndGgobmV3LmNsdXN0ZXJzKSkpCgkJY29sbmFtZXMoZW5yaWNoLmRmKSA8LSBjKDMsIDE3LCAxMCwgMTEpCgkJcm93bmFtZXMoZW5yaWNoLmRmKSA8LSBuZXcuY2x1c3RlcnMKCQltZXRhLmRmIDwtIGNtcC5vYmplY3RAbWV0YS5kYXRhCgkJZm9yKHJvdy5pZCBpbiByb3duYW1lcyhlbnJpY2guZGYpKXsKCQkJdG90LmNsdXMgPC0gbnJvdyhtZXRhLmRmW21ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkLF0pCgkJCWZvcihjb2wuaWQgaW4gY29sbmFtZXMoZW5yaWNoLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbKG1ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkKSAmIChtZXRhLmRmJGNsdXN0LklEID09IGNvbC5pZCksXSkKCQkJCXBjdC54IDwtIGFzLmludGVnZXIobnVtLnggLyB0b3QuY2x1cyAqMTAwKQoJCQkJIyBwcmludChwY3QueCkKCQkJCWVucmljaC5kZltyb3cuaWQsIGNvbC5pZF0gPC0gcGN0LngKCQkJfQoJCX0KCQljb2xuYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShjb2xuYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm9sZGNsdXN0ZXIiLCB4KSkKCQlyb3duYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShyb3duYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm5ld2NsdXN0ZXIiLCB4KSkKCQl4bHN4Ojp3cml0ZS54bHN4KGVucmljaC5kZiwgZmlsZSA9IHBhc3RlMCgiUGN0T2ZOZXdDbHVzdGVyc092ZXJsYXBwaW5nT2xkQ2x1c3RlcnNfIiwgcHJvamVjdE5hbWUsICJfZGltIiwgbmRpbXMsICIueGxzeCIpLCBzaGVldE5hbWUgPSBwYXN0ZTAoZ3N1YigiUk5BX3Nubl8iLCAiIiwgbWV0YS5jb2wpKSwgYXBwZW5kID0gVFJVRSkKCQlwcmludChlbnJpY2guZGYpCgl9Cn0KCmBgYApBYnNvbHV0ZWx5IHRlcnJpYmxlIG92ZXJsYXAsIG5vIGVucmljaG1lbnQgb2YgYW55IG9mIHRoZXNlIGFjcm9zcyB0aGUgbmV3IGNsdXN0ZXJpbmcgYWxnb3JpdGhtLiBNYXliZSBzaG91bGQgdHJ5IDk1JSB2YXJpYXRpb24gY292ZXJlZAoKIyMgRmluZCBvbGQgY2VsbHMgb24gVU1BUAoKdGltZSBmb3IgdGhlIHN1cGVyIHNjYXJleSBtb21lbnQgdG8gc2VlIGlmIHRoZSBjZWxscyBmcm9tIHNldXJhdHYxIHN0aWxsIGNsdXN0ZXIgdG9nZXRoZXIgb24gaW4gc2V1cmF0IHY0CgpgYGB7ciBmaWcud2lkdGggPSA0fQpEaW1QbG90KGNtcC5vYmplY3QsCgkJCQlyZWR1Y3Rpb24gPSAidW1hcCIsCgkJCQlncm91cC5ieSA9ICJjbHVzdC5JRCIsIAoJCQkJIyBzcGxpdC5ieSA9ICJvcmlnLmlkZW50IiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCmBgYHtyIGZpZy53aWR0aCA9IDR9CkRpbVBsb3QoY21wLm9iamVjdCwKCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwKCQkJCWdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCAKCQkJCXNwbGl0LmJ5ID0gImNsdXN0LklEIiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCgoKIyBUb3RhbCB2YXIgODUlCiMjIE5laWdoYm9yaG9vZCBhbmQgdW1hcApzZXQgdG90YWwudmFyIDwtIDg1JQpgYGB7cn0KdG90LnZhciA8LSBwZXJjZW50LnZhcmlhbmNlKGNtcC5vYmplY3RAcmVkdWN0aW9ucyRwY2FAc3RkZXYsIHBsb3QudmFyID0gRkFMU0UsIHJldHVybi52YWwgPSBUUlVFKQpuZGltcyA8LSBsZW5ndGgod2hpY2goY3Vtc3VtKHRvdC52YXIpIDw9IDg1KSkKYGBgCgpgYGB7cn0KY21wLm9iamVjdCA8LSBGaW5kTmVpZ2hib3JzKGNtcC5vYmplY3QsIGRpbXMgPSAxOm5kaW1zKQpjbXAub2JqZWN0IDwtIEZpbmRDbHVzdGVycyhjbXAub2JqZWN0LCByZXNvbHV0aW9uID0gMC41KQpjbXAub2JqZWN0IDwtIFJ1blVNQVAoY21wLm9iamVjdCwgZGltcyA9IDE6IG5kaW1zKQpgYGAKUGxvdCBVTUFQCgpgYGB7cn0KZm9yKHggaW4gYygwLjUsIDEsIDEuNSwgMiwgMi41KSl7CgljbXAub2JqZWN0IDwtIEZpbmRDbHVzdGVycyhjbXAub2JqZWN0LCByZXNvbHV0aW9uID0geCkKc2F2ZVJEUyhjbXAub2JqZWN0LCBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX2RpbSIsIG5kaW1zLCAiLlJEUyIpKQp9CmBgYAoKYGBge3J9CmZvciAobWV0YS5jb2wgaW4gY29sbmFtZXMoY21wLm9iamVjdEBtZXRhLmRhdGEpKXsKCWlmKGdyZXBsKHBhdHRlcm4gPSAoIlJOQV9zbm5fcmVzIiksIHggPSBtZXRhLmNvbCk9PVRSVUUpewoJCXBsb3QudGl0bGUgPC0gcGFzdGUwKHByb2plY3ROYW1lLCAiZGltIiwgbmRpbXMsICJyZXMiLCBnc3ViKCJSTkFfc25uX3JlcyIsICIiLCBtZXRhLmNvbCkpCgkJbXlwbG90IDwtIERpbVBsb3QoY21wLm9iamVjdCwgCgkJCQkJCQkJCQkJZ3JvdXAuYnkgPSBtZXRhLmNvbCwKCQkJCQkJCQkJCQlyZWR1Y3Rpb24gPSAidW1hcCIsIAoJCQkJCQkJCQkJCWNvbHMgPSBjb2xvci5wYWxldHRlCgkJCQkJCQkJCQkJKSArIAoJCQlnZ3RpdGxlKHBsb3QudGl0bGUpCgkJcGxvdChteXBsb3QpCgkJcG5nKGZpbGVuYW1lID0gcGFzdGUwKHBsb3QudGl0bGUsICIucG5nIiksIGhlaWdodCA9IDgwMCwgd2lkdGggPSA4MDApCgkJcGxvdChEaW1QbG90KGNtcC5vYmplY3QsIAoJCQkJCQkJCQkJCWdyb3VwLmJ5ID0gbWV0YS5jb2wsCgkJCQkJCQkJCQkJcmVkdWN0aW9uID0gInVtYXAiLCAKCQkJCQkJCQkJCQljb2xzID0gY29sb3IucGFsZXR0ZSwgCgkJCQkJCQkJCQkJcHQuc2l6ZSA9IDEuNQoJCQkJCQkJCQkJCSkgKyAKCQkJZ2d0aXRsZShwbG90LnRpdGxlKQoJCQkpCgkJZGV2Lm9mZigpCgl9Cn0KYGBgCgojIyMgQ2x1c3RyZWUKd2hhdCdzIHRoZSBtYXggcmVzb2x1dGlvbiB3ZSBjYW4gYWNoaWV2ZSB3aGlsZSBrZWVwaWduIGNsdXN0ZXJzIHN0YWJsZT8KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA1fQpwbG90LnRpdGxlIDwtIHBhc3RlMChwcm9qZWN0TmFtZSwgIl9jbHVzdHJlZV9uZGltIiwgbWF4KGNtcC5vYmplY3RAY29tbWFuZHMkUnVuVU1BUC5STkEucGNhJGRpbXMpKQpteS5jbHVzdHJlZSA8LSBjbHVzdHJlZShjbXAub2JqZWN0LCBwcmVmaXggPSAiUk5BX3Nubl9yZXMuIiwgbm9kZV9jb2xvdXIgPSAic2MzX3N0YWJpbGl0eSIsIGV4cHJzID0gInNjYWxlLmRhdGEiKSArIAoJc2NhbGVfY29sb3JfY29udGludW91cyhsb3cgPSAncmVkMycsIGhpZ2ggPSAnd2hpdGUnKSArIAoJZ2d0aXRsZShwbG90LnRpdGxlKQpwbmcoZmlsZW5hbWUgPSBwYXN0ZTAocGxvdC50aXRsZSwgIi5wbmciKSwgaGVpZ2h0ID0gODAwLCB3aWR0aCA9IDE2MDApCnBsb3QobXkuY2x1c3RyZWUpCmRldi5vZmYoKQpgYGAKCgoKZm9yIGVhY2ggcmVzb2x1dGlvbiwgbnVtYmVyL3BlcmNlbnRhZ2Ugb2YgY2VsbHMgaW4gZWFjaCBjbHVzdGVyPwoKYGBge3J9CnRvdC5jZWxscyA8LSBucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhKQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQluZXcuY2x1c3RlcnMgPC0gc29ydChhcy5udW1lcmljKGxldmVscyhjbXAub2JqZWN0QG1ldGEuZGF0YVtbbWV0YS5jb2xdXSkpKQoJCXN0YXRzLmRmIDwtIGRhdGEuZnJhbWUobWF0cml4KG5jb2wgPSAyLCBucm93ID0gbGVuZ3RoKG5ldy5jbHVzdGVycykpKQoJCWNvbG5hbWVzKHN0YXRzLmRmKSA8LSBjKCJudW1fY2VsbHMiLCAicGN0X3BvcCIpCgkJcm93bmFtZXMoc3RhdHMuZGYpIDwtIG5ldy5jbHVzdGVycwoJCW1ldGEuZGYgPC0gY21wLm9iamVjdEBtZXRhLmRhdGEKCQlmb3Iocm93LmlkIGluIHJvd25hbWVzKHN0YXRzLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbbWV0YS5kZlttZXRhLmNvbF0gPT0gcm93LmlkLF0pCgkJCQlwY3QueCA8LSBhcy5pbnRlZ2VyKG51bS54IC8gdG90LmNlbGxzICoxMDApCgkJCQkjIHByaW50KHBjdC54KQoJCQkJc3RhdHMuZGZbcm93LmlkLCAibnVtX2NlbGxzIl0gPC0gbnVtLngKCQkJCXN0YXRzLmRmW3Jvdy5pZCwgInBjdF9wb3AiXSA8LSBwY3QueAoJCX0KCQlwcmludChzdGF0cy5kZikKCX0KfQpgYGAKCiMjIElkZW50aWZ5IHZhcmlhYmxlIGdlbmVzIGZvciBuZXcgYmlvbWFyawpgYGB7cn0KbGVuZ3RoKGNtcC5vYmplY3RAYXNzYXlzJFJOQUB2YXIuZmVhdHVyZXMpCmBgYAoKCgoKCiMjIyBHZW5lIHByb2ZpbGVzIG9mIGNsdXN0ZXJzCnNldCBpZGVudCBhdCByZXMgPSAxIGFuZCBnZXQgbWFya2VycwpgYGB7cn0KSWRlbnRzKGNtcC5vYmplY3QpIDwtICJSTkFfc25uX3Jlcy4xIgpjbXAuYWxsbWFya2Vycy5yZXMxIDwtIEZpbmRBbGxNYXJrZXJzKGNtcC5vYmplY3QpCmNtcC50b3AxMDBtYXJrZXJzLnJlczEgPC0gY21wLmFsbG1hcmtlcnMucmVzMSAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG4gPSAxMDAsIHd0ID0gYWJzKGF2Z19sb2cyRkMpKQpgYGAKCmBgYHtyfQpjbXAudG9wMTAwbWFya2Vycy5yZXMxIDwtIGNtcC5hbGxtYXJrZXJzLnJlczEgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuID0gMTAwLCB3dCA9IGFicyhhdmdfbG9nMkZDKSkKY21wLnRvcDEwMG1hcmtlcnMucmVzMSA8LSBjbXAudG9wMTAwbWFya2Vycy5yZXMxW2NtcC50b3AxMDBtYXJrZXJzLnJlczEkcF92YWxfYWRqIDw9IDAuMDUsIF0KZm9yKGNsdXN0ZXIgaW4gdW5pcXVlKGNtcC50b3AxMDBtYXJrZXJzLnJlczEkY2x1c3RlcikpewoJbnVtLmhpdHMgPC0gbnJvdyhjbXAudG9wMTAwbWFya2Vycy5yZXMxW2NtcC50b3AxMDBtYXJrZXJzLnJlczEkY2x1c3RlciA9PSBjbHVzdGVyLCBdKQoJcHJpbnQocGFzdGUoImNsdXN0ZXIiLCBjbHVzdGVyLCAiaGFzIiwgbnVtLmhpdHMsICJnZW5lcyIpKQp9CmBgYAoKCkZpbmQgdG9wLnZhcglnZW5lcyBpbiBjbXAudG9wMTAwbWFya2Vycy5yZXMxCmBgYHtyfQp0b3AudmFyIDwtIGNtcC5vYmplY3RAYXNzYXlzJFJOQUB2YXIuZmVhdHVyZXNbMToxNTBdCiMgdG9wLnZhcgpuLnZhcmdlbmVzIDwtIGMoKQpmb3IoZ2VuZSBpbiB0b3AudmFyKXsKCWlmKGdlbmUgJWluJSBjbXAudG9wMTAwbWFya2Vycy5yZXMxJGdlbmUpewoJCW4udmFyZ2VuZXMgPC0gYyhuLnZhcmdlbmVzLCBnZW5lKQoJfQp9CnByaW50KGxlbmd0aChuLnZhcmdlbmVzKSkKdG9wLnZhclshKHRvcC52YXIgJWluJSBuLnZhcmdlbmVzKV0KYGBgCgoKTGV0cyB0cnkgdG8gZXhwb3J0IHRoZXNlLCB3aXRoIGdlbmVzIG9uIHJvd3MgYW5kIGNsdXN0ZXJzIG9uIGNvbHVtbnMsIGFuZCB4cHJlc3Npb24gdmFsdWUgaW4gZGF0YSB0YWJsZQpgYGB7cn0KdmFyLmRmIDwtIGNtcC50b3AxMDBtYXJrZXJzLnJlczFbY21wLnRvcDEwMG1hcmtlcnMucmVzMSRnZW5lICVpbiUgbi52YXJnZW5lcyxdCnZhci5kZiA8LSBzdWJzZXQuZGF0YS5mcmFtZSh2YXIuZGYsIHNlbGVjdCA9IGMoImdlbmUiLCAiY2x1c3RlciIsICJhdmdfbG9nMkZDIikpCnZhci5kZiA8LSByZXNoYXBlMjo6ZGNhc3QodmFyLmRmLCBnZW5lfmNsdXN0ZXIsIHZhbHVlLnZhciA9ICJhdmdfbG9nMkZDIikKeGxzeDo6d3JpdGUueGxzeCh2YXIuZGYsIGZpbGUgPSBwYXN0ZTAocHJvamVjdE5hbWUsICJfZGltIiwgbmRpbXMsICJfY2FuZGlkaWRhdGVCaW9tYXJrR2VuZXMueGxzeCIpLCBzaGVldE5hbWUgPSAicmVzMSIsIGFwcGVuZCA9IFRSVUUsIHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpIZXJlJ3MgdGhlIGxpc3Qgb2YgZ2VuZXMsIHBsdXMgc29tZSBjb250cm9scwpgYGB7cn0KcmVzMS5iaW9tYXJrLmdlbmVzIDwtIGMoIkFpZjEiLAoiQXFwMSIsCiJCaXJjNSIsCiJDY2wzIiwKIkNjcjIiLAoiQ2Q3NCIsCiJDZGMyMCIsCiJDZW5wZiIsCiJDc3QzIiwKIkN0c2giLAoiRG50dCIsCiJFbGFuZSIsCiJFcm1hcCIsCiJGMTNhMSIsCiJGY2VyMWciLAoiR20xNTkxNSIsCiJHbTE3NTkwIiwKIkgyLUFhIiwKIkgyLUViMSIsCiJIMmFmeCIsCiJIMmFmeSIsCiJIaXN0MWgyYWMiLAoiSG1nYjIiLAoiSHAiLAoiSWdobSIsCiJJcmY4IiwKIkxnYWxzMyIsCiJMbW80IiwKIk1zNGEyIiwKIk10MSIsCiJQbGFjOCIsCiJQcnRuMyIsCiJSYXAxYiIsCiJSZ3MxIiwKIlZ3ZiIsCiJXZmRjMTciLAoiQ3NycDMiLAoiSGlzdDFoMmFlIiwKIklmaXRtMSIsCiJMZ2FsczEiLAoiVG1zYjR4IiwKIkFybDZpcDEiLAoiQ2FyMiIsCiJDY2w5IiwKIkNjbmIyIiwKIkNkOSIsCiJDZW5wYSIsCiJDcGEzIiwKIkZvcyIsCiJIaXN0MWgyYXAiLAoiTHk2YzIiLAoiTXBvIiwKIlBjbGFmIiwKIlNscGkiLAoiVG9wMmEiLAoiVWJlMmMiLAoiTHk4NiIsCiJIaXN0MWgyYmMiLAoiUGY0IiwKIkFwb2UiLAoiQ3RzZyIsCiJDYXIxIiwKIkhtbXIiLCAKIkdhcGRoIiwgCiJCMm0iLCAKIkFjdGIiLCAKIkhwcnQxIiwKIkd1c2IiKQpgYGAKCm1ha2UgdmxuIHBsb3RzIHBlciBjbHVzdGVyCmBgYHtyfQpmb3IoZ2VuZSBpbiByZXMxLmJpb21hcmsuZ2VuZXMpewoJcGxvdC50aXRsZSA8LSBwYXN0ZTAocHJvamVjdE5hbWUsICJkaW0iLCBuZGltcywgInJlczFfIiwgZ2VuZSkKCW15cGxvdDwtIFZsblBsb3QoY21wLm9iamVjdCwgZmVhdHVyZXMgPSBnZW5lLCBwdC5zaXplID0gMC4wMSkgKyBnZ3RpdGxlKHBsb3QudGl0bGUpCglwbmcoZmlsZW5hbWUgPSBwYXN0ZTAocGxvdC50aXRsZSwgIi5wbmciKSwgaGVpZ2h0ID0gODAwLCB3aWR0aCA9IDE2MDApCglwbG90KG15cGxvdCkKCWRldi5vZmYoKQoJCn0KYGBgCgoKIyMgUmVzIDEuNQoKcmVwZWF0IGZvciB0b3AudmFyCWdlbmVzIGluIGNtcC50b3AxMDBtYXJrZXJzLnJlczEuNQpgYGB7cn0KdG9wLnZhciA8LSBjbXAub2JqZWN0QGFzc2F5cyRSTkFAdmFyLmZlYXR1cmVzWzE6MTUwXQpJZGVudHMoY21wLm9iamVjdCkgPC0gIlJOQV9zbm5fcmVzLjEuNSIKY21wLmFsbG1hcmtlcnMucmVzMS41IDwtIEZpbmRBbGxNYXJrZXJzKGNtcC5vYmplY3QpCmNtcC50b3AxMDBtYXJrZXJzLnJlczEuNSA8LSBjbXAuYWxsbWFya2Vycy5yZXMxLjUgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuID0gMTAwLCB3dCA9IGFicyhhdmdfbG9nMkZDKSkKbi52YXJnZW5lcyA8LSBjKCkKZm9yKGdlbmUgaW4gdG9wLnZhcil7CglpZihnZW5lICVpbiUgY21wLnRvcDEwMG1hcmtlcnMucmVzMS41JGdlbmUpewoJCW4udmFyZ2VuZXMgPC0gYyhuLnZhcmdlbmVzLCBnZW5lKQoJfQp9CnByaW50KGxlbmd0aChuLnZhcmdlbmVzKSkKdG9wLnZhclshKHRvcC52YXIgJWluJSBuLnZhcmdlbmVzKV0KYGBgCgoKTGV0cyB0cnkgdG8gZXhwb3J0IHRoZXNlLCB3aXRoIGdlbmVzIG9uIHJvd3MgYW5kIGNsdXN0ZXJzIG9uIGNvbHVtbnMsIGFuZCB4cHJlc3Npb24gdmFsdWUgaW4gZGF0YSB0YWJsZQpgYGB7cn0KdmFyLmRmIDwtIGNtcC50b3AxMDBtYXJrZXJzLnJlczEuNVtjbXAudG9wMTAwbWFya2Vycy5yZXMxLjUkZ2VuZSAlaW4lIG4udmFyZ2VuZXMsXQp2YXIuZGYgPC0gc3Vic2V0LmRhdGEuZnJhbWUodmFyLmRmLCBzZWxlY3QgPSBjKCJnZW5lIiwgImNsdXN0ZXIiLCAiYXZnX2xvZzJGQyIpKQp2YXIuZGYgPC0gcmVzaGFwZTI6OmRjYXN0KHZhci5kZiwgZ2VuZX5jbHVzdGVyKQp4bHN4Ojp3cml0ZS54bHN4KHZhci5kZiwgZmlsZSA9IHBhc3RlMChwcm9qZWN0TmFtZSwgIl9kaW0iLCBuZGltcywgIl9jYW5kaWRpZGF0ZUJpb21hcmtHZW5lcy54bHN4IiksIHNoZWV0TmFtZSA9ICJyZXMxLjUiLCBhcHBlbmQgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCmBgYApGb3IgZWFjaCByZXNvbHV0aW9uLCB3aGF0IHBlcmNlbnRhZ2Ugb2YgY2VsbHMgaW4gZWFjaCBjbHVzdGVyIGFyZSBlbnJpY2hlZCBmb3Igb25lIG9mIG91ciBjbHVzdC5JRHM/CgoKVGVzdDogd2hhdCBwZXJjZW50YWdlIG9mIGVhY2ggbmV3IGNsdXN0ZXJJRCBtYXRjaGVzIG9uZSBvZiB0aGUgb2xkZXIgY2x1c3RlcnM/CmBgYHtyfQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQluZXcuY2x1c3RlcnMgPC0gc29ydChhcy5udW1lcmljKGxldmVscyhjbXAub2JqZWN0QG1ldGEuZGF0YVtbbWV0YS5jb2xdXSkpKQoJCWVucmljaC5kZiA8LSBkYXRhLmZyYW1lKG1hdHJpeChuY29sID0gNCwgbnJvdyA9IGxlbmd0aChuZXcuY2x1c3RlcnMpKSkKCQljb2xuYW1lcyhlbnJpY2guZGYpIDwtIGMoMywgMTcsIDEwLCAxMSkKCQlyb3duYW1lcyhlbnJpY2guZGYpIDwtIG5ldy5jbHVzdGVycwoJCW1ldGEuZGYgPC0gY21wLm9iamVjdEBtZXRhLmRhdGEKCQlmb3Iocm93LmlkIGluIHJvd25hbWVzKGVucmljaC5kZikpewoJCQl0b3QuY2x1cyA8LSBucm93KG1ldGEuZGZbbWV0YS5kZltbbWV0YS5jb2xdXSA9PSByb3cuaWQsXSkKCQkJZm9yKGNvbC5pZCBpbiBjb2xuYW1lcyhlbnJpY2guZGYpKXsKCQkJCW51bS54IDwtIG5yb3cobWV0YS5kZlsobWV0YS5kZltbbWV0YS5jb2xdXSA9PSByb3cuaWQpICYgKG1ldGEuZGYkY2x1c3QuSUQgPT0gY29sLmlkKSxdKQoJCQkJcGN0LnggPC0gYXMuaW50ZWdlcihudW0ueCAvIHRvdC5jbHVzICoxMDApCgkJCQkjIHByaW50KHBjdC54KQoJCQkJZW5yaWNoLmRmW3Jvdy5pZCwgY29sLmlkXSA8LSBwY3QueAoJCQl9CgkJfQoJCWNvbG5hbWVzKGVucmljaC5kZikgPC0gc2FwcGx5KGNvbG5hbWVzKGVucmljaC5kZiksIGZ1bmN0aW9uKHgpIHBhc3RlMCgib2xkY2x1c3RlciIsIHgpKQoJCXJvd25hbWVzKGVucmljaC5kZikgPC0gc2FwcGx5KHJvd25hbWVzKGVucmljaC5kZiksIGZ1bmN0aW9uKHgpIHBhc3RlMCgibmV3Y2x1c3RlciIsIHgpKQoJCXhsc3g6OndyaXRlLnhsc3goZW5yaWNoLmRmLCBmaWxlID0gcGFzdGUwKCJQY3RPZk5ld0NsdXN0ZXJzT3ZlcmxhcHBpbmdPbGRDbHVzdGVyc18iLCBwcm9qZWN0TmFtZSwgIl9kaW0iLCBuZGltcywgIi54bHN4IiksIHNoZWV0TmFtZSA9IHBhc3RlMChnc3ViKCJSTkFfc25uXyIsICIiLCBtZXRhLmNvbCkpLCBhcHBlbmQgPSBUUlVFKQoJCXByaW50KGVucmljaC5kZikKCX0KfQoKYGBgCkFic29sdXRlbHkgdGVycmlibGUgb3ZlcmxhcCwgbm8gZW5yaWNobWVudCBvZiBhbnkgb2YgdGhlc2UgYWNyb3NzIHRoZSBuZXcgY2x1c3RlcmluZyBhbGdvcml0aG0uIE1heWJlIHNob3VsZCB0cnkgOTUlIHZhcmlhdGlvbiBjb3ZlcmVkCgojIyBGaW5kIG9sZCBjZWxscyBvbiBVTUFQCgp0aW1lIGZvciB0aGUgc3VwZXIgc2NhcmV5IG1vbWVudCB0byBzZWUgaWYgdGhlIGNlbGxzIGZyb20gc2V1cmF0djEgc3RpbGwgY2x1c3RlciB0b2dldGhlciBvbiBpbiBzZXVyYXQgdjQKCmBgYHtyIGZpZy53aWR0aCA9IDR9CkRpbVBsb3QoY21wLm9iamVjdCwKCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwKCQkJCWdyb3VwLmJ5ID0gImNsdXN0LklEIiwgCgkJCQkjIHNwbGl0LmJ5ID0gIm9yaWcuaWRlbnQiLAoJCQkJY29scyA9IGMoImdyYXkiLCAib3JhbmdlIiwgImJsdWUiLCAicmVkIiwgImdyZWVuIiksKQpgYGAKYGBge3IgZmlnLndpZHRoID0gNH0KRGltUGxvdChjbXAub2JqZWN0LAoJCQkJcmVkdWN0aW9uID0gInVtYXAiLAoJCQkJZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIAoJCQkJc3BsaXQuYnkgPSAiY2x1c3QuSUQiLAoJCQkJY29scyA9IGMoImdyYXkiLCAib3JhbmdlIiwgImJsdWUiLCAicmVkIiwgImdyZWVuIiksKQpgYGAKCiMjIyBHZW5lIGV4cHJlc3Npb24gb2Ygb2xkIGNsdXN0cnMgb24gbmV3IG1hcApMZXQncyBzZWUgaWYgd2UgY2FuIGdldCBzb21lIGdlbmUgZXhwcmVzc2lvbiBwcm9maWxlcyBvbiB0aGVzZS4uLgpgYGB7ciwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE4fQpnZW5lLmxpc3QgPC0gYygiR2F0YTEiLCAiR2F0YTIiLCAiUGY0IiwgIkRudHQiLCAiTXBvIiwgIk1laXMxIiwgIklyZjgiLCAiRWxhbmUiLCAiRmxpMSIsICJaZnBtMSIpClZsblBsb3QoY21wLm9iamVjdCwgZmVhdHVyZXMgPSBnZW5lLmxpc3QsIGdyb3VwLmJ5ID0gImNsdXN0LklEIiwgcHQuc2l6ZSA9IDAuMDEsIGNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpKQpgYGAKCgojIFRvdGFsIHZhciA4MCUKIyMgTmVpZ2hib3Job29kIGFuZCB1bWFwCnNldCB0b3RhbC52YXIgPC0gODAlCmBgYHtyfQp0b3QudmFyIDwtIHBlcmNlbnQudmFyaWFuY2UoY21wLm9iamVjdEByZWR1Y3Rpb25zJHBjYUBzdGRldiwgcGxvdC52YXIgPSBGQUxTRSwgcmV0dXJuLnZhbCA9IFRSVUUpCm5kaW1zIDwtIGxlbmd0aCh3aGljaChjdW1zdW0odG90LnZhcikgPD0gODApKQoKY21wLm9iamVjdCA8LSBGaW5kTmVpZ2hib3JzKGNtcC5vYmplY3QsIGRpbXMgPSAxOm5kaW1zKQpjbXAub2JqZWN0IDwtIEZpbmRDbHVzdGVycyhjbXAub2JqZWN0LCByZXNvbHV0aW9uID0gMC41KQpjbXAub2JqZWN0IDwtIFJ1blVNQVAoY21wLm9iamVjdCwgZGltcyA9IDE6IG5kaW1zKQoKYGBgClBsb3QgVU1BUAoKYGBge3J9CmZvcih4IGluIGMoMC41LCAxLCAxLjUsIDIsIDIuNSkpewoJY21wLm9iamVjdCA8LSBGaW5kQ2x1c3RlcnMoY21wLm9iamVjdCwgcmVzb2x1dGlvbiA9IHgpCnNhdmVSRFMoY21wLm9iamVjdCwgZmlsZSA9IHBhc3RlMChwcm9qZWN0TmFtZSwgIl9kaW0iLCBuZGltcywgIi5SRFMiKSkKfQpgYGAKCmBgYHtyfQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQlteXBsb3QgPC0gRGltUGxvdChjbXAub2JqZWN0LCAKCQkJCQkJCQkJCQlncm91cC5ieSA9IG1ldGEuY29sLAoJCQkJCQkJCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwgCgkJCQkJCQkJCQkJY29scyA9IGNvbG9yLnBhbGV0dGUKCQkJCQkJCQkJCQkpICsgCgkJCWdndGl0bGUocGFzdGUwKHByb2plY3ROYW1lLCAiIGRpbSIsIG5kaW1zLCAicmVzIiwgZ3N1YigiUk5BX3Nubl9yZXMiLCAiIiwgbWV0YS5jb2wpICkpCgkJcGxvdChteXBsb3QpCgl9Cn0KYGBgCgojIyMgQ2x1c3RyZWUKd2hhdCdzIHRoZSBtYXggcmVzb2x1dGlvbiB3ZSBjYW4gYWNoaWV2ZSB3aGlsZSBrZWVwaWduIGNsdXN0ZXJzIHN0YWJsZT8KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA1fQpwbG90LnRpdGxlIDwtIHBhc3RlMChwcm9qZWN0TmFtZSwgIl9jbHVzdHJlZV9uZGltIiwgbWF4KGNtcC5vYmplY3RAY29tbWFuZHMkUnVuVU1BUC5STkEucGNhJGRpbXMpKQpteS5jbHVzdHJlZSA8LSBjbHVzdHJlZShjbXAub2JqZWN0LCBwcmVmaXggPSAiUk5BX3Nubl9yZXMuIiwgbm9kZV9jb2xvdXIgPSAic2MzX3N0YWJpbGl0eSIsIGV4cHJzID0gInNjYWxlLmRhdGEiKSArIAoJc2NhbGVfY29sb3JfY29udGludW91cyhsb3cgPSAncmVkMycsIGhpZ2ggPSAnd2hpdGUnKSArIAoJZ2d0aXRsZShwbG90LnRpdGxlKQpwbmcoZmlsZW5hbWUgPSBwYXN0ZTAocGxvdC50aXRsZSwgIi5wbmciKSwgaGVpZ2h0ID0gODAwLCB3aWR0aCA9IDE2MDApCnBsb3QobXkuY2x1c3RyZWUpCmRldi5vZmYoKQpgYGAKCgoKZm9yIGVhY2ggcmVzb2x1dGlvbiwgbnVtYmVyL3BlcmNlbnRhZ2Ugb2YgY2VsbHMgaW4gZWFjaCBjbHVzdGVyPwoKYGBge3J9CnRvdC5jZWxscyA8LSBucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhKQpmb3IgKG1ldGEuY29sIGluIGNvbG5hbWVzKGNtcC5vYmplY3RAbWV0YS5kYXRhKSl7CglpZihncmVwbChwYXR0ZXJuID0gKCJSTkFfc25uX3JlcyIpLCB4ID0gbWV0YS5jb2wpPT1UUlVFKXsKCQluZXcuY2x1c3RlcnMgPC0gc29ydChhcy5udW1lcmljKGxldmVscyhjbXAub2JqZWN0QG1ldGEuZGF0YVtbbWV0YS5jb2xdXSkpKQoJCXN0YXRzLmRmIDwtIGRhdGEuZnJhbWUobWF0cml4KG5jb2wgPSAyLCBucm93ID0gbGVuZ3RoKG5ldy5jbHVzdGVycykpKQoJCWNvbG5hbWVzKHN0YXRzLmRmKSA8LSBjKCJudW1fY2VsbHMiLCAicGN0X3BvcCIpCgkJcm93bmFtZXMoc3RhdHMuZGYpIDwtIG5ldy5jbHVzdGVycwoJCW1ldGEuZGYgPC0gY21wLm9iamVjdEBtZXRhLmRhdGEKCQlmb3Iocm93LmlkIGluIHJvd25hbWVzKHN0YXRzLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbbWV0YS5kZlttZXRhLmNvbF0gPT0gcm93LmlkLF0pCgkJCQlwY3QueCA8LSBhcy5pbnRlZ2VyKG51bS54IC8gdG90LmNlbGxzICoxMDApCgkJCQkjIHByaW50KHBjdC54KQoJCQkJc3RhdHMuZGZbcm93LmlkLCAibnVtX2NlbGxzIl0gPC0gbnVtLngKCQkJCXN0YXRzLmRmW3Jvdy5pZCwgInBjdF9wb3AiXSA8LSBwY3QueAoJCX0KCQlwcmludChzdGF0cy5kZikKCX0KfQpgYGAKCgoKRm9yIGVhY2ggcmVzb2x1dGlvbiwgd2hhdCBwZXJjZW50YWdlIG9mIGNlbGxzIGluIGVhY2ggY2x1c3RlciBhcmUgZW5yaWNoZWQgZm9yIG9uZSBvZiBvdXIgY2x1c3QuSURzPwoKClRlc3Q6IHdoYXQgcGVyY2VudGFnZSBvZiBlYWNoIG5ldyBjbHVzdGVySUQgbWF0Y2hlcyBvbmUgb2YgdGhlIG9sZGVyIGNsdXN0ZXJzPwpgYGB7cn0KZm9yIChtZXRhLmNvbCBpbiBjb2xuYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkpewoJaWYoZ3JlcGwocGF0dGVybiA9ICgiUk5BX3Nubl9yZXMiKSwgeCA9IG1ldGEuY29sKT09VFJVRSl7CgkJbmV3LmNsdXN0ZXJzIDwtIHNvcnQoYXMubnVtZXJpYyhsZXZlbHMoY21wLm9iamVjdEBtZXRhLmRhdGFbW21ldGEuY29sXV0pKSkKCQllbnJpY2guZGYgPC0gZGF0YS5mcmFtZShtYXRyaXgobmNvbCA9IDQsIG5yb3cgPSBsZW5ndGgobmV3LmNsdXN0ZXJzKSkpCgkJY29sbmFtZXMoZW5yaWNoLmRmKSA8LSBjKDMsIDE3LCAxMCwgMTEpCgkJcm93bmFtZXMoZW5yaWNoLmRmKSA8LSBuZXcuY2x1c3RlcnMKCQltZXRhLmRmIDwtIGNtcC5vYmplY3RAbWV0YS5kYXRhCgkJZm9yKHJvdy5pZCBpbiByb3duYW1lcyhlbnJpY2guZGYpKXsKCQkJdG90LmNsdXMgPC0gbnJvdyhtZXRhLmRmW21ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkLF0pCgkJCWZvcihjb2wuaWQgaW4gY29sbmFtZXMoZW5yaWNoLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbKG1ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkKSAmIChtZXRhLmRmJGNsdXN0LklEID09IGNvbC5pZCksXSkKCQkJCXBjdC54IDwtIGFzLmludGVnZXIobnVtLnggLyB0b3QuY2x1cyAqMTAwKQoJCQkJIyBwcmludChwY3QueCkKCQkJCWVucmljaC5kZltyb3cuaWQsIGNvbC5pZF0gPC0gcGN0LngKCQkJfQoJCX0KCQljb2xuYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShjb2xuYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm9sZGNsdXN0ZXIiLCB4KSkKCQlyb3duYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShyb3duYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm5ld2NsdXN0ZXIiLCB4KSkKCQl4bHN4Ojp3cml0ZS54bHN4KGVucmljaC5kZiwgZmlsZSA9IHBhc3RlMCgiUGN0T2ZOZXdDbHVzdGVyc092ZXJsYXBwaW5nT2xkQ2x1c3RlcnNfIiwgcHJvamVjdE5hbWUsICJfZGltIiwgbmRpbXMsICIueGxzeCIpLCBzaGVldE5hbWUgPSBwYXN0ZTAoZ3N1YigiUk5BX3Nubl8iLCAiIiwgbWV0YS5jb2wpKSwgYXBwZW5kID0gVFJVRSkKCQlwcmludChlbnJpY2guZGYpCgl9Cn0KCmBgYApBYnNvbHV0ZWx5IHRlcnJpYmxlIG92ZXJsYXAsIG5vIGVucmljaG1lbnQgb2YgYW55IG9mIHRoZXNlIGFjcm9zcyB0aGUgbmV3IGNsdXN0ZXJpbmcgYWxnb3JpdGhtLiBNYXliZSBzaG91bGQgdHJ5IDk1JSB2YXJpYXRpb24gY292ZXJlZAoKIyMgRmluZCBvbGQgY2VsbHMgb24gVU1BUAoKdGltZSBmb3IgdGhlIHN1cGVyIHNjYXJleSBtb21lbnQgdG8gc2VlIGlmIHRoZSBjZWxscyBmcm9tIHNldXJhdHYxIHN0aWxsIGNsdXN0ZXIgdG9nZXRoZXIgb24gaW4gc2V1cmF0IHY0CgpgYGB7ciBmaWcud2lkdGggPSA0fQpEaW1QbG90KGNtcC5vYmplY3QsCgkJCQlyZWR1Y3Rpb24gPSAidW1hcCIsCgkJCQlncm91cC5ieSA9ICJjbHVzdC5JRCIsIAoJCQkJIyBzcGxpdC5ieSA9ICJvcmlnLmlkZW50IiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCmBgYHtyIGZpZy53aWR0aCA9IDR9CkRpbVBsb3QoY21wLm9iamVjdCwKCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwKCQkJCWdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCAKCQkJCXNwbGl0LmJ5ID0gImNsdXN0LklEIiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCgoKCiMgVG90YWwgdmFyIDk1JQoKIyMgTmVpZ2hib3Job29kIGFuZCB1bWFwCnNldCB0b3RhbC52YXIgPC0gOTUlCmBgYHtyfQp0b3QudmFyIDwtIHBlcmNlbnQudmFyaWFuY2UoY21wLm9iamVjdEByZWR1Y3Rpb25zJHBjYUBzdGRldiwgcGxvdC52YXIgPSBGQUxTRSwgcmV0dXJuLnZhbCA9IFRSVUUpCm5kaW1zIDwtIGxlbmd0aCh3aGljaChjdW1zdW0odG90LnZhcikgPD0gOTUpKQoKY21wLm9iamVjdCA8LSBGaW5kTmVpZ2hib3JzKGNtcC5vYmplY3QsIGRpbXMgPSAxOm5kaW1zKQpjbXAub2JqZWN0IDwtIEZpbmRDbHVzdGVycyhjbXAub2JqZWN0LCByZXNvbHV0aW9uID0gMC41KQpjbXAub2JqZWN0IDwtIFJ1blVNQVAoY21wLm9iamVjdCwgZGltcyA9IDE6IG5kaW1zKQoKYGBgClBsb3QgVU1BUAoKYGBge3J9CmZvcih4IGluIGMoMC41LCAxLCAxLjUsIDIsIDIuNSkpewoJY21wLm9iamVjdCA8LSBGaW5kQ2x1c3RlcnMoY21wLm9iamVjdCwgcmVzb2x1dGlvbiA9IHgpCn0Kc2F2ZVJEUyhjbXAub2JqZWN0LCBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX2RpbSIsIG5kaW1zLCAiLlJEUyIpKQpgYGAKCmBgYHtyfQpjbXAub2JqZWN0IDwtIHJlYWRSRFMoIkNNUF9kaW00MS5SRFMiKQpgYGAKCgpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDV9CnBsb3QudGl0bGUgPC0gcGFzdGUwKHByb2plY3ROYW1lLCAiX2NsdXN0cmVlX25kaW0iLCBtYXgoY21wLm9iamVjdEBjb21tYW5kcyRSdW5VTUFQLlJOQS5wY2EkZGltcykpCm15LmNsdXN0cmVlIDwtIGNsdXN0cmVlKGNtcC5vYmplY3QsIHByZWZpeCA9ICJSTkFfc25uX3Jlcy4iLCBub2RlX2NvbG91ciA9ICJzYzNfc3RhYmlsaXR5IiwgZXhwcnMgPSAic2NhbGUuZGF0YSIpICsgCglzY2FsZV9jb2xvcl9jb250aW51b3VzKGxvdyA9ICdyZWQzJywgaGlnaCA9ICd3aGl0ZScpICsgCglnZ3RpdGxlKHBsb3QudGl0bGUpCnBuZyhmaWxlbmFtZSA9IHBhc3RlMChwbG90LnRpdGxlLCAiLnBuZyIpLCBoZWlnaHQgPSA4MDAsIHdpZHRoID0gMTYwMCkKcGxvdChteS5jbHVzdHJlZSkKZGV2Lm9mZigpCmBgYAoKRm9yIGVhY2ggcmVzb2x1dGlvbiwgd2hhdCBwZXJjZW50YWdlIG9mIGNlbGxzIGluIGVhY2ggY2x1c3RlciBhcmUgZW5yaWNoZWQgZm9yIG9uZSBvZiBvdXIgY2x1c3QuSURzPwoKClRlc3Q6IHdoYXQgcGVyY2VudGFnZSBvZiBlYWNoIG5ldyBjbHVzdGVySUQgbWF0Y2hlcyBvbmUgb2YgdGhlIG9sZGVyIGNsdXN0ZXJzPwpgYGB7cn0KZm9yIChtZXRhLmNvbCBpbiBjb2xuYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkpewoJaWYoZ3JlcGwocGF0dGVybiA9ICgiUk5BX3Nubl9yZXMiKSwgeCA9IG1ldGEuY29sKT09VFJVRSl7CgkJbmV3LmNsdXN0ZXJzIDwtIHNvcnQoYXMubnVtZXJpYyhsZXZlbHMoY21wLm9iamVjdEBtZXRhLmRhdGFbW21ldGEuY29sXV0pKSkKCQllbnJpY2guZGYgPC0gZGF0YS5mcmFtZShtYXRyaXgobmNvbCA9IDQsIG5yb3cgPSBsZW5ndGgobmV3LmNsdXN0ZXJzKSkpCgkJY29sbmFtZXMoZW5yaWNoLmRmKSA8LSBjKDMsIDE3LCAxMCwgMTEpCgkJcm93bmFtZXMoZW5yaWNoLmRmKSA8LSBuZXcuY2x1c3RlcnMKCQltZXRhLmRmIDwtIGNtcC5vYmplY3RAbWV0YS5kYXRhCgkJZm9yKHJvdy5pZCBpbiByb3duYW1lcyhlbnJpY2guZGYpKXsKCQkJdG90LmNsdXMgPC0gbnJvdyhtZXRhLmRmW21ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkLF0pCgkJCWZvcihjb2wuaWQgaW4gY29sbmFtZXMoZW5yaWNoLmRmKSl7CgkJCQludW0ueCA8LSBucm93KG1ldGEuZGZbKG1ldGEuZGZbW21ldGEuY29sXV0gPT0gcm93LmlkKSAmIChtZXRhLmRmJGNsdXN0LklEID09IGNvbC5pZCksXSkKCQkJCXBjdC54IDwtIGFzLmludGVnZXIobnVtLnggLyB0b3QuY2x1cyAqMTAwKQoJCQkJIyBwcmludChwY3QueCkKCQkJCWVucmljaC5kZltyb3cuaWQsIGNvbC5pZF0gPC0gcGN0LngKCQkJfQoJCX0KCQljb2xuYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShjb2xuYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm9sZGNsdXN0ZXIiLCB4KSkKCQlyb3duYW1lcyhlbnJpY2guZGYpIDwtIHNhcHBseShyb3duYW1lcyhlbnJpY2guZGYpLCBmdW5jdGlvbih4KSBwYXN0ZTAoIm5ld2NsdXN0ZXIiLCB4KSkKCQl4bHN4Ojp3cml0ZS54bHN4KGVucmljaC5kZiwgZmlsZSA9IHBhc3RlMCgiUGN0T2ZOZXdDbHVzdGVyc092ZXJsYXBwaW5nT2xkQ2x1c3RlcnNfIiwgcHJvamVjdE5hbWUsICJfZGltIiwgbmRpbXMsICIueGxzeCIpLCBzaGVldE5hbWUgPSBwYXN0ZTAoZ3N1YigiUk5BX3Nubl8iLCAiIiwgbWV0YS5jb2wpKSwgYXBwZW5kID0gVFJVRSkKCQlwcmludChlbnJpY2guZGYpCgl9Cn0KCmBgYApBYnNvbHV0ZWx5IHRlcnJpYmxlIG92ZXJsYXAsIG5vIGVucmljaG1lbnQgb2YgYW55IG9mIHRoZXNlIGFjcm9zcyB0aGUgbmV3IGNsdXN0ZXJpbmcgYWxnb3JpdGhtLiBNYXliZSBzaG91bGQgdHJ5IDk1JSB2YXJpYXRpb24gY292ZXJlZAoKIyMgRmluZCBvbGQgY2VsbHMgb24gVU1BUAoKdGltZSBmb3IgdGhlIHN1cGVyIHNjYXJleSBtb21lbnQgdG8gc2VlIGlmIHRoZSBjZWxscyBmcm9tIHNldXJhdHYxIHN0aWxsIGNsdXN0ZXIgdG9nZXRoZXIgb24gaW4gc2V1cmF0IHY0CgpgYGB7ciBmaWcud2lkdGggPSAyfQpEaW1QbG90KGNtcC5vYmplY3QsCgkJCQlyZWR1Y3Rpb24gPSAidW1hcCIsCgkJCQlncm91cC5ieSA9ICJjbHVzdC5JRCIsIAoJCQkJcHQuc2l6ZSA9IC4xLAoJCQkJIyBzcGxpdC5ieSA9ICJvcmlnLmlkZW50IiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCmBgYHtyIGZpZy53aWR0aCA9IDR9CkRpbVBsb3QoY21wLm9iamVjdCwKCQkJCXJlZHVjdGlvbiA9ICJ1bWFwIiwKCQkJCWdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCAKCQkJCXNwbGl0LmJ5ID0gImNsdXN0LklEIiwKCQkJCWNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpLCkKYGBgCgoKCiMjIyBHZW5lIGV4cHJlc3Npb24gb2Ygb2xkIGNsdXN0cnMgb24gbmV3IG1hcApMZXQncyBzZWUgaWYgd2UgY2FuIGdldCBzb21lIGdlbmUgZXhwcmVzc2lvbiBwcm9maWxlcyBvbiB0aGVzZS4uLgpgYGB7ciwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE4fQpnZW5lLmxpc3QgPC0gYygiR2F0YTEiLCAiR2F0YTIiLCAiUGY0IiwgIkRudHQiLCAiTXBvIiwgIk1laXMxIiwgIklyZjgiLCAiRWxhbmUiLCAiRmxpMSIsICJaZnBtMSIpClZsblBsb3QoY21wLm9iamVjdCwgZmVhdHVyZXMgPSBnZW5lLmxpc3QsIGdyb3VwLmJ5ID0gImNsdXN0LklEIiwgcHQuc2l6ZSA9IDAuMDEsIGNvbHMgPSBjKCJncmF5IiwgIm9yYW5nZSIsICJibHVlIiwgInJlZCIsICJncmVlbiIpKQpgYGAKCgpVc2VkIHRoZSBleGNlIGRvYyB0byBkbyBzb21lIGZhbmN5IGNvbmRpdGlvbmFsIGZvcm1hdHRpbmcuIE9sZCBjbHVzdGVyIDE3IGlzIHByZXR0eSBkaXNwZXJzZWQgdW50aWwgeW91IGl0IHJlc29sdXRpb24gMi41LiBPdGhlcmlzZSwgY2VsbHMgaW4gb2xkIGNsdXN0ZXIgMTcgZG8gbm90IGNvbnN0aXR1dGUgbW9yZSB0aGFuIDQwJSBvZiBhbnkgY2VsbHMgaW4gdGhlIG5ldyBjbHVzdGVycy4gIApBcyBmYXIgYXMgSSBjYW4gc2VlLCB0aGUgdHdvIGFwcHJvYWNoZXMgYXJlIHRvIGRvIERHRW9mIG5ldyBDTVAgdy8gcmVzb2x1dGlvbiA9IDIuNSwgQU5EL09SIGRvIERHZSB1c2luZyBvbGRlciBjbHVzdGVyIElEcy4gU3VyZSBzZWVtcyB0byBtYWtlIHNlbnNlIHRvIGRvIGJvdGguLi4KCgojIERHRSB3LyByZXNvbHV0aW9uID0gMi41ClN0cnQgd2l0aCBjb21wYXJpbmcgYWxsIGNsdXN0ZXJzIGFnYWluc3QgYWxsIG90aGVyIGNsdXN0ZXJzCldyaXRlIG91dCBjbHVzdGVyIGluZm8KCgpjYWxjdWxhdGUgYEZpbmRBbGxNYXJrZXJzKClgIGZvciBkaWZmZXJlbnQgaWRlbnRzIGFuZCBzYXZlIHRvIG5ldyBmaWxlCmBgYHtyfQppZGVudC5saXN0IDwtIGMoIlJOQV9zbm5fcmVzLjAuNSIsICJSTkFfc25uX3Jlcy4xIiwgIlJOQV9zbm5fcmVzLjEuNSIsICJSTkFfc25uX3Jlcy4yIiwgIlJOQV9zbm5fcmVzLjIuNSIsICJjbHVzdC5JRCIpCmZvcih0ZXN0ZWQuaWRlbnQgaW4gaWRlbnQubGlzdCl7CglJZGVudHMoY21wLm9iamVjdCkgPC0gdGVzdGVkLmlkZW50CglhbGwubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhjbXAub2JqZWN0KQoJeGxzeDo6d3JpdGUueGxzeCh4ID0gYWxsLm1hcmtlcnNbLGMoImF2Z19sb2cyRkMiLCAicF92YWxfYWRqIiwgImNsdXN0ZXIiLCAiZ2VuZSIpXSwgCgkJCQkJCQkJCSBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX0ZpbmRBTExNYXJrZXJzX3JlczIuNS54bHN4IiksIAoJCQkJCQkJCQkgc2hlZXROYW1lID0gdGVzdGVkLmlkZW50LCAKCQkJCQkJCQkJIGNvbC5uYW1lcyA9IFRSVUUsIAoJCQkJCQkJCQkgcm93Lm5hbWVzID0gRkFMU0UsIAoJCQkJCQkJCQkgYXBwZW5kID0gVFJVRSkKfQpgYGAKCkNyZWF0ZSBgRmluZEFsbE1hcmtlcnMoKWAgbGlzdHMgZm9yIEdTRUEKYGBge3IgfQpJZGVudHMoY21wLm9iamVjdCkgPC0gIlJOQV9zbm5fcmVzLjIuNSIKcmVzLjIuNS5hbGxtYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKGNtcC5vYmplY3QpCmBgYAoKIyMgTWFwIEhHTkMgc3ltYm9scwpgYGB7cn0KTW91c2UySHVtYW5UYWJsZSA8LSBNb3VzZTJIdW1hbihyZXMuMi41LmFsbG1hcmtlcnMkZ2VuZSkKCkhHTkMgPC0gd2l0aChNb3VzZTJIdW1hblRhYmxlLCBNb3VzZTJIdW1hblRhYmxlJEhHTkNbbWF0Y2gocmVzLjIuNS5hbGxtYXJrZXJzJGdlbmUsIE1vdXNlMkh1bWFuVGFibGUkTUdJKV0pCmhlYWQocmVzLjIuNS5hbGxtYXJrZXJzKQpyZXMuMi41LmFsbG1hcmtlcnMkSEdOQyA8LSBIR05DCnRhaWwocmVzLjIuNS5hbGxtYXJrZXJzKQpzaWcucmVzLjIuNSA8LSByZXMuMi41LmFsbG1hcmtlcnNbcmVzLjIuNS5hbGxtYXJrZXJzJHBfdmFsX2FkaiA8PSAwLjA1LCBdCnNpZy5yZXMuMi41IDwtIHNpZy5yZXMuMi41W2MoImF2Z19sb2cyRkMiLCAiSEdOQyIsICJjbHVzdGVyIildCnNpZy5yZXMuMi41IDwtIHNpZy5yZXMuMi41WyEoc2lnLnJlcy4yLjUkSEdOQyA9PSAiIiB8IGlzLm5hKHNpZy5yZXMuMi41JEhHTkMpKSxdICMgR1NFQSB3aWxsIGZhaWwgaWYgdGhlcmUgYXJlIGFueSBibGFua3Mgb3IgTkFzIGluIHRoZSB0YWJsZQpzaWcucmVzLjIuNSA8LSBzaWcucmVzLjIuNVtdCgpgYGAKCgpgYGB7cn0KZm9yKGNsdXN0ZXIgaW4gdW5pcXVlKHNpZy5yZXMuMi41JGNsdXN0ZXIpKXsKCXByaW50KHBhc3RlKCJ3cml0aW5nIGNsdXN0ZXIiLCBjbHVzdGVyKSkKCW5ldy50YWJsZSA8LSBzaWcucmVzLjIuNVtzaWcucmVzLjIuNSRjbHVzdGVyID09IGNsdXN0ZXIsIGMoIkhHTkMiLCAiYXZnX2xvZzJGQyIpXQoJbmV3LnRhYmxlIDwtIG5ldy50YWJsZVtvcmRlcigtbmV3LnRhYmxlJGF2Z19sb2cyRkMpLCBdCgl3cml0ZS50YWJsZShuZXcudGFibGUsIGZpbGUgPSBwYXN0ZTAoIlJhbmtMaXN0X3JlczIuNV9maW5kQWxsX2hnbmMvcmVzLjIuNWNsdXN0ZXIiLCBjbHVzdGVyLCAiLnJuayIpLCBxdW90ZSA9IEZBTFNFLCByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSwgc2VwID0gIlx0IiwgKQoJCn0KYGBgCgoKCmNhbGN1bGF0ZSBgRmluZE1hcmtlcnMoKWAgdGhhdCBkaXN0aW5ndWlzaCBlYWNoIGNsdXN0ZXIgKG1pZ2h0IG92ZXJsYWIgYmV0d2VlbiBjbHVzdGVycykKYGBge3J9CmlkZW50Lmxpc3QgPC0gYygiUk5BX3Nubl9yZXMuMC41IiwgIlJOQV9zbm5fcmVzLjEiLCAiUk5BX3Nubl9yZXMuMS41IiwgIlJOQV9zbm5fcmVzLjIiLCAiUk5BX3Nubl9yZXMuMi41IiwgImNsdXN0LklEIikKZm9yKHRlc3RlZC5pZGVudCBpbiBpZGVudC5saXN0KXsKCW9iamVjdC5jb3B5IDwtIGNtcC5vYmplY3QKCUlkZW50cyhvYmplY3QuY29weSkgPC0gdGVzdGVkLmlkZW50CglwcmludChwYXN0ZSgidGVzdGluZyIsIHRlc3RlZC5pZGVudCkpCglmb3IgKGNsdXN0ZXIgaW4gc29ydChhcy5udW1lcmljKGxldmVscyhvYmplY3QuY29weUBtZXRhLmRhdGFbW3Rlc3RlZC5pZGVudF1dKSkpKXsKCQlwcmludChwYXN0ZSgibG9va2luZyBhdCBjbHVzdGVyIiwgY2x1c3RlcikpCgkJY2x1c3Rlci5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdC5jb3B5LCBpZGVudC4xID0gY2x1c3RlcikKCQl0cnkoCgkJCXhsc3g6OndyaXRlLnhsc3goeCA9IGNsdXN0ZXIubWFya2Vyc1ssYygiYXZnX2xvZzJGQyIsICJwX3ZhbF9hZGoiKV0sIAoJCQkJCQkJCQkJCSBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX0ZpbmRNYXJrZXJzXyIsIGdzdWIoIlJOQV9zbm5fIiwgIiIsIHRlc3RlZC5pZGVudCksICIueGxzeCIpLCAKCQkJCQkJCQkJCQkgc2hlZXROYW1lID0gcGFzdGUwKCJjbHN0IiwgY2x1c3RlciksIAoJCQkJCQkJCQkJCSBjb2wubmFtZXMgPSBUUlVFLCAKCQkJCQkJCQkJCQkgcm93Lm5hbWVzID0gVFJVRSwgCgkJCQkJCQkJCQkJIGFwcGVuZCA9IFRSVUUpCgkJKQkKCX0KCXJlbW92ZShvYmplY3QuY29weSkKfQpgYGAKCgoKYGBge3J9CmZvciAoY2x1c3RlciBpbiBzb3J0KGFzLm51bWVyaWMobGV2ZWxzKGNtcC5vYmplY3RAbWV0YS5kYXRhJFJOQV9zbm5fcmVzLjIuNSkpKSl7CgljbHVzdGVyLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMoY21wLm9iamVjdCwgaWRlbnQuMSA9IGNsdXN0ZXIpCgl4bHN4Ojp3cml0ZS54bHN4KHggPSBjbHVzdGVyLm1hcmtlcnNbLGMoImF2Z19sb2cyRkMiLCAicF92YWxfYWRqIildLCAKCQkJCQkJCQkJIGZpbGUgPSBwYXN0ZTAocHJvamVjdE5hbWUsICJfRmluZE1hcmtlcnNfcmVzMi41Lnhsc3giKSwgCgkJCQkJCQkJCSBzaGVldE5hbWUgPSBwYXN0ZTAoImNsc3QiLCBjbHVzdGVyKSwgCgkJCQkJCQkJCSBjb2wubmFtZXMgPSBUUlVFLCAKCQkJCQkJCQkJIHJvdy5uYW1lcyA9IFRSVUUsIAoJCQkJCQkJCQkgYXBwZW5kID0gVFJVRSkKfQpgYGAKCiMjIENvbWJpbmUgY2x1c3RlcnMgdGhhdCBtaWdodCByZXByZXNlbnQgb2xkIGNsdXN0ZXIgaWRzCgojIERHRSB3LyBtZXRhZGF0YSBhZ2FpbnN0IGNsdXN0LklEIGFnYWluc3QgIjAiCnJlc2V0IGlkZW50IGFzICJjbHVzdC5JRCIgYW5kIHJlcnVuIGBGaW5kQWxsTWFya2VycygpYApgYGB7cn0KCUlkZW50cyhjbXAub2JqZWN0KSA8LSAiY2x1c3QuSUQiCglhbGwubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhjbXAub2JqZWN0KQoJeGxzeDo6d3JpdGUueGxzeCh4ID0gYWxsLm1hcmtlcnNbLGMoImF2Z19sb2cyRkMiLCAicF92YWxfYWRqIiwgImNsdXN0ZXIiLCAiZ2VuZSIpXSwgCgkJCQkJCQkJCSBmaWxlID0gcGFzdGUwKHByb2plY3ROYW1lLCAiX0ZpbmRBTExNYXJrZXJzX2NsdXN0SUQueGxzeCIpLCAKCQkJCQkJCQkJIHNoZWV0TmFtZSA9ICJjbHVzdElEIiwgCgkJCQkJCQkJCSBjb2wubmFtZXMgPSBUUlVFLCAKCQkJCQkJCQkJIHJvdy5uYW1lcyA9IEZBTFNFLCAKCQkJCQkJCQkJIGFwcGVuZCA9IFRSVUUpCmBgYAoKCmBgYHtyfQojIElkZW50cyhjbXAub2JqZWN0KSA8LSAiY2x1c3QuSUQiCmZvciAoY2x1c3RlciBpbiB1bmlxdWUoY21wLm9iamVjdEBtZXRhLmRhdGEkY2x1c3QuSUQpKXsKCXByaW50KGNsdXN0ZXIpCgljbHVzdGVyLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMoY21wLm9iamVjdCwgaWRlbnQuMSA9IGNsdXN0ZXIpCgl4bHN4Ojp3cml0ZS54bHN4KHggPSBjbHVzdGVyLm1hcmtlcnNbLGMoImF2Z19sb2cyRkMiLCAicF92YWxfYWRqIildLCAKCQkJCQkJCQkJIGZpbGUgPSBwYXN0ZTAocHJvamVjdE5hbWUsICJfRmluZE1hcmtlcnNfY2x1c3RJRC54bHN4IiksIAoJCQkJCQkJCQkgc2hlZXROYW1lID0gcGFzdGUwKCJvbGRjbHVzdCIsIGNsdXN0ZXIpLCAKCQkJCQkJCQkJIGNvbC5uYW1lcyA9IFRSVUUsIAoJCQkJCQkJCQkgcm93Lm5hbWVzID0gVFJVRSwgCgkJCQkJCQkJCSBhcHBlbmQgPSBUUlVFKQp9CgpgYGAKCgojIERpc3Rpbmd1aXNoaW5nIGZlYXR1cmVzIG9mIGNsdXN0ZXJzClByZXZpb3VzbHkgZGVmaW5lZCBiaW9tYXJrIGdlbmVzIGJhc2VkIG9uIFBDIGNvbnRyaWJ1dGlvbnMuIE9yaWdpbmFsIGxpc3Qgd2FzIGJhc2VkIG9uICphbGwqIG1zQWdnciwgYnV0IGxldCdzIHNlZSBob3cgQ01QIHN1YnNldCBkb2VzPwpgYGB7ciBmaWcuaGVpZ2h0ID0gMzAsIGZpZy53aWR0aD02fQpWaXpEaW1Mb2FkaW5ncyhjbXAub2JqZWN0LCBkaW1zID0gMToxMCwgbmZlYXR1cmVzID0gMzAsIHJlZHVjdGlvbiA9ICJwY2EiLCBuY29sID0gMikKYGBgCgpgYGB7cn0KcGNhLmRmIDwtIGNtcC5vYmplY3RbWyJwY2EiXV0KcGNhLmRmIDwtIGFzLmRhdGEuZnJhbWUoYXMubWF0cml4KHNsb3Qob2JqZWN0ID0gcGNhLmRmLCBuYW1lID0gImZlYXR1cmUubG9hZGluZ3MiKSkpCnByaW50KGNtcC5vYmplY3RbWyJwY2EiXV0sIGRpbXMgPSAyLCBuZmVhdHVyZXMgPSA1KQpyb3duYW1lcyhwY2EuZGZbcGNhLmRmJFBDXzIgJWluJSBzb3J0KHBjYS5kZiRQQ18yLCBkZWNyZWFzaW5nID0gVFJVRSlbMTo1XSwgXSkKcm93bmFtZXMocGNhLmRmW3BjYS5kZiRQQ18yICVpbiUgc29ydChwY2EuZGYkUENfMilbMTo1XSwgXSkKYGBgCgpub3cgd2UgY2FuIGdldCBhIGxpc3Qgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMhICAKZmlyc3QgcHVsbCB0aGUgbGlzdCBvZiBvbGRBbmFseXNpcyBDTVAgdG9wIFBDIGdlbmVzCmBgYHtyfQpjbXAuYmlvbWFyayA8LSByZWFkLnRhYmxlKGZpbGUgPSAiL1VzZXJzL2hldXN0b25lZi9EZXNrdG9wL0NNUFN1YnBvcHMvQmlvTWFyay9Qcm9iZVBhbmVscy9DTVBfUENUb3BHZW5lcy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBUUlVFKQpiaW9tYXJrLmNtcHRhcmdldHMgPC0gYygpCmZvcihkZi5jb2wgaW4gMTpuY29sKGNtcC5iaW9tYXJrKSl7CgliaW9tYXJrLmNtcHRhcmdldHMgPC0gYyhiaW9tYXJrLmNtcHRhcmdldHMsIGJpb21hcmtbLGRmLmNvbF0pCn0KcHJpbnQoY29sbmFtZXMoYmlvbWFyaykpCnByaW50KHBhc3RlKCJ0b3RhbCBnZW5lIGNvdW50OiIsIGxlbmd0aChiaW9tYXJrLmNtcHRhcmdldHMpKSkKYGBgCgpOb3cgZ2V0IHRoZSBsaXN0IG9mIGN1cnJlbnQgcGMgZ2VuZSB0cmdldHMgKG9sZEFuYWx5c2lzIHVzZWQgbmRpbSA9IDE6Niwgc28gd2UnbGwgc3RhcnQgd2l0aCB0aGF0IHJhbmdlKQpgYGB7cn0KcGMubGlzdCA8LSBjKCJQQ18xIiwgIlBDXzIiLCAiUENfMyIsICJQQ180IiwgIlBDXzUiLCAiUENfNiIpCnBjLmdlbmVzIDwtIGxhcHBseShwYy5saXN0LCBmdW5jdGlvbih4KSByb3duYW1lcyhwY2EuZGZbcGNhLmRmW1t4XV0gJWluJSBzb3J0KHBjYS5kZltbeF1dLCBkZWNyZWFzaW5nID0gVFJVRSlbMTozMF0sXSkpICN0YXJnZXRpbmcgcm91Z2hseSAxODAgZ2VuZXMgbGlrZSBpbiBiaW9tYXJrLmNtcHRhcmdldHMKcGMuZ2VuZXMgPC0gdW5pcXVlKHVubGlzdChwYy5nZW5lcykpCnByaW50KHBhc3RlKCJ0b3RhbCBnZW5lIGNvdW50OiIsIGxlbmd0aChwYy5nZW5lcykpKQpgYGAKCk5vdyBjb21wYXJlIHRoZSBsaXN0cywgSSBndWVzczoKCmBgYHtyfQojIHNldGRpZmYoeCx5KSBnaXZlcyB5b3UgdGhpbmdzIGluIHggbm90IGluIHkuIHNldGRpZmYoeSx4KSBnaXZlcyB5b3UgdGhpbmdzIGluIHkgbm90IGluIHgKc2V0ZGlmZihiaW9tYXJrLmNtcHRhcmdldHMsIHBjLmdlbmVzKQojIHByaW50KHBhc3RlKCJcbiBsZW5ndGg6IiwgbGVuZ3RoKHNldGRpZmYoYmlvbWFyay5jbXB0YXJnZXRzLCBwYy5nZW5lcykpKSkKd3JpdGVMaW5lcyhjKCIiLCAibGVuZ3RoOiIsIGxlbmd0aChzZXRkaWZmKGJpb21hcmsuY21wdGFyZ2V0cywgcGMuZ2VuZXMpKSkpCmBgYApVbW0sIHllYWggdGhhdCB3ZW50IGtpbmRhIGhvdyBJIGV4cGVjdGVkLiBMZXQncyBkbyB0aGlzIGFnYWluLCBidXQgZm9yIHRoZSBhY3R1YWwgYmlvbWFyayBnZW5lIGxpc3RzLgpgYGB7cn0KYmlvbWFyayA8LSByZWFkLnRhYmxlKGZpbGUgPSAiL1VzZXJzL2hldXN0b25lZi9EZXNrdG9wL0NNUFN1YnBvcHMvQmlvTWFyay9Qcm9iZVBhbmVscy9CaW9tYXJrUHJvYmVMaXN0LnR4dCIsIHNlcCA9ICJcdCIpCmJpb21hcmsgPC0gYmlvbWFya1ssMV0Kc2V0ZGlmZihiaW9tYXJrLCBwYy5nZW5lcykKd3JpdGVMaW5lcyhjKCIiLCAibGVuZ3RoOiIsIGxlbmd0aChzZXRkaWZmKGJpb21hcmssIHBjLmdlbmVzKSkpKQpgYGAKCgpXaGF0IGlmIHdlIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgcGNzIGJ1dCBkZWNyZWFzZSB0aGUgZGVwdGggb2YgZWFjaD8gVGhpcyBtaWdodCBjb3ZlciBtb3JlIG9mIGBiaW9tYXJrCWAsIHdoaWNoIHdhcyBvcmlnaW5hbGx5IGRldmVsb3BlZCB1c2luZyBtc0FnZ3IgaW5zdGVhZCBvZiBvbmx5IHRoZSBDTVAgc3Vic2V0CmBgYHtyfQpwYy5saXN0IDwtIGMoIlBDXzEiLCAiUENfMiIsICJQQ18zIiwgIlBDXzQiLCAiUENfNSIsICJQQ182IiwgIlBDXzciLCAiUENfOCIsICJQQ185IiwgIlBDXzEwIikKcGMuZ2VuZXMgPC0gbGFwcGx5KHBjLmxpc3QsIGZ1bmN0aW9uKHgpIHJvd25hbWVzKHBjYS5kZltwY2EuZGZbW3hdXSAlaW4lIHNvcnQocGNhLmRmW1t4XV0sIGRlY3JlYXNpbmcgPSBUUlVFKVsxOjIwXSxdKSkKcGMuZ2VuZXMgPC0gdW5pcXVlKHVubGlzdChwYy5nZW5lcykpCnByaW50KHBhc3RlKCJ0b3RhbCBnZW5lIGNvdW50OiIsIGxlbmd0aChwYy5nZW5lcykpKQoKYGBgCmBgYHtyfQpzZXRkaWZmKGJpb21hcmssIHBjLmdlbmVzKQp3cml0ZUxpbmVzKGMoIiIsICJsZW5ndGg6IiwgbGVuZ3RoKHNldGRpZmYoYmlvbWFyaywgcGMuZ2VuZXMpKSkpCmBgYAoKRm9yIGNvbXBhcmlzb24sIGxldCdzIGp1c3Qgc2VlIGhvdyBtYW55IG9mIGBiaW9tYXJrLmNtcHRhcmdldHNgIHdlcmUgYWN0dWFsbHkgaW5jbHVkZWQgaW4gYGJpb21hcmtgCmBgYHtyfQpzZXRkaWZmKGJpb21hcmsuY21wdGFyZ2V0cywgYmlvbWFyaykKd3JpdGVMaW5lcyhjKCIiLCAibGVuZ3RoOiIsIGxlbmd0aChzZXRkaWZmKGJpb21hcmsuY21wdGFyZ2V0cywgcGMuZ2VuZXMpKSkpCmBgYApgYGB7cn0KbGVuZ3RoKGJpb21hcmspIC0gbGVuZ3RoKHNldGRpZmYoYmlvbWFyaywgYmlvbWFyay5jbXB0YXJnZXRzKSkKYGBgCmBgYHtyfQpsZW5ndGgoYmlvbWFyaykgLSBsZW5ndGgoc2V0ZGlmZihiaW9tYXJrLCBwYy5nZW5lcykpCmBgYApTbyB3aGVuIHlvdSBsb29rIGF0IGl0IGxpa2UgdGhhdCwgaXQncyBub3QgYWN0dWFsbHkgdGhhdCBmYXIgb2ZmLgoKCldoYXQgYXJlIHRoZSBzaW1pbGFyaXRpZXM/OgpgYGB7cn0Kc2V0ZGlmZihzZXRkaWZmKGJpb21hcmssIGJpb21hcmsuY21wdGFyZ2V0cyksIHNldGRpZmYoYmlvbWFyaywgcGMuZ2VuZXMpKQpgYGAKVGhlc2UgYXJlIGdlbmVzIGZyb20gdGhlIDk3cHJvYmVzIG5vdCBpbiB0aGUgb2xkIENNUCBzZXQgdGhhdCBhcmUgYWxzbyBub3QgaW4gdGhlIG5ldyBDTVAgc2V0LiBPdGhlciB0aGFuIEl0Z2EyYiAod2hpY2ggaXMgYSBmYWlsZWQgcHJvYmUgYW55d2F5KSwgbm90aGluZyBzY3JlYW1zLiBBbHNvIHdlJ2QgaGF2ZSB0aHJvd24gRmx0MyBhbmQgQ2QzNCBmb3IgaW4gYW55d2F5IGJlY2F1c2UgdGhleSdyZSByZXF1aXNpdGUgY2VsbCBzdXJmYWNlIG1hcmtlcnMgKGFsc28gRmx0MyBzdXJmYWNlIG1hcmtlciBpcyBleHBlbnNpdmUgYnV0IG90aGVyd2lzZSBub3Qgbm90ZXdvcnRoeSBhbmQgbm90IHVzZWQgaW4gdGhlIGN1cnJlbnQgc29ydGluZyBzdHJhdGVneSkKCldoYXQgYWJvdXQgY2VsbCBzdXJmYWNlIG1hcmtlciBleHByZXNzaW9uPwoqIENkMzQKKiBDZDE2LzMyCiogQ2Q5CiogQ2Q0MQoqIENkNDgKKiBTY2ExIChqdXN0IHRocm93IHRoYXQgaW4gZm9yIHNoKiZzIGFuZCBnaWdnbGVzKQpgYGB7ciwgZmlnLmhlaWdodCA9IDE1LCBmaWcud2lkdGg9MTB9CnN1cmZhY2UubWFya2VycyA8LSBjKCJDZDM0IiwgIkZjZ3IzIiwgIkZjZ3IyYiIsICJDZDkiLCAiSXRnYTJiIiwgIkNkNDgiLCAiTHk2YSIpCkZlYXR1cmVQbG90KGNtcC5vYmplY3QsIGZlYXR1cmVzID0gc3VyZmFjZS5tYXJrZXJzLCBwdC5zaXplID0gMSwgc3BsaXQuYnkgPSAiY2x1c3QuSUQiLCBuY29sID0gMSkKYGBgClNhdmUgYXMgcG5nCmBgYHtyfQpwbmcoZmlsZW5hbWUgPSAiRmVhdHVyZVBsb3RfQ01QX3N1cmZhY2VNYXJrZXJzX2NsdXN0SURmYWNldC5wbmciLCBoZWlnaHQgPSAxNjAwLCB3aWR0aCA9IDE2MDApCkZlYXR1cmVQbG90KGNtcC5vYmplY3QsIGZlYXR1cmVzID0gc3VyZmFjZS5tYXJrZXJzLCBwdC5zaXplID0gMSwgc3BsaXQuYnkgPSAiY2x1c3QuSUQiLCBuY29sID0gMSkKZGV2Lm9mZigpCmBgYAoKCgoKCgoKIyBDb21wYXJlIEBnIGhpZXJhcmNoY2lhbCBjbHVzdGVpcm5nCgpEbyBjbHVzdGVyaW5nIHVzaW5nIGJpb21hcmsgUk5BcyBhcyBpbnB1dApgYGB7cn0KIyBSZWFkIGluIEJpb21hcmtSTkFzCmJpb21hcmsucm5hcyA8LSByZWFkLnRhYmxlKCcvVXNlcnMvaGV1c3RvbmVmL0Rlc2t0b3AvMTBYR2Vub21pY3NEYXRhL0Jpb21hcmtSTkFzLnR4dCcpCmJpb21hcmsucm5hcyA8LSBiaW9tYXJrLnJuYXMkVjEKYGBgCgp1c2UgYmlvbWFyayBSTkFzIHRvIGRlZmluZSBkaW1lbnNpb25hbCByZWR1Y3Rpb24KYGBge3J9CmNtcC5vYmplY3QgPC0gcmVhZFJEUygiQ01QX3Jhdy5SRFMiKQpjbXAub2JqZWN0IDwtIFJ1blBDQShjbXAub2JqZWN0LCBmZWF0dXJlcyA9IGJpb21hcmsucm5hcywgbmRpbXMucHJpbnQgPSAxOjUsICwgbmZlYXR1cmVzLnByaW50ID0gNSkKRWxib3dQbG90KGNtcC5vYmplY3QsIG5kaW1zID0gNTApCmBgYAoKCk5vdyBydW4gdGhlIGNsdXN0ZXJpbmcKYGBge3J9CnRvdC52YXIgPC0gcGVyY2VudC52YXJpYW5jZShjbXAub2JqZWN0QHJlZHVjdGlvbnMkcGNhQHN0ZGV2LCBwbG90LnZhciA9IEZBTFNFLCByZXR1cm4udmFsID0gVFJVRSkKbmRpbXMgPC0gbGVuZ3RoKHdoaWNoKGN1bXN1bSh0b3QudmFyKSA8PSA5MCkpCgpjbXAub2JqZWN0IDwtIEZpbmROZWlnaGJvcnMoY21wLm9iamVjdCwgZGltcyA9IDE6bmRpbXMpCmNtcC5vYmplY3QgPC0gRmluZENsdXN0ZXJzKGNtcC5vYmplY3QsIHJlc29sdXRpb24gPSAwLjUpCmNtcC5vYmplY3QgPC0gUnVuVU1BUChjbXAub2JqZWN0LCBkaW1zID0gMTogbmRpbXMpCgoKYGBgCgpmaW5kIHRoZSBjbHVzdGVycwoKYGBge3J9CmZvcih4IGluIGMoMC41LCAxLCAxLjUsIDIsIDIuNSkpewoJY21wLm9iamVjdCA8LSBGaW5kQ2x1c3RlcnMoY21wLm9iamVjdCwgcmVzb2x1dGlvbiA9IHgpCn0KYGBgCgpQbG90IHRoZSB1bWFwcyBhbmQgY2VsbCBjbHVzdGVyIGlkcwpgYGB7cn0KZm9yIChtZXRhLmNvbCBpbiBjb2xuYW1lcyhjbXAub2JqZWN0QG1ldGEuZGF0YSkpewoJaWYoZ3JlcGwocGF0dGVybiA9ICgiUk5BX3Nubl9yZXMiKSwgeCA9IG1ldGEuY29sKT09VFJVRSl7CgkJbXlwbG90IDwtIERpbVBsb3QoY21wLm9iamVjdCwgCgkJCQkJCQkJCQkJZ3JvdXAuYnkgPSBtZXRhLmNvbCwKCQkJCQkJCQkJCQlyZWR1Y3Rpb24gPSAidW1hcCIsIAoJCQkJCQkJCQkJCWNvbHMgPSBjb2xvci5wYWxldHRlCgkJCQkJCQkJCQkJKSArIAoJCQlnZ3RpdGxlKHBhc3RlMChwcm9qZWN0TmFtZSwgIiBkaW0iLCBuZGltcywgInJlcyIsIGdzdWIoIlJOQV9zbm5fcmVzIiwgIiIsIG1ldGEuY29sKSApKQoJCXBsb3QobXlwbG90KQoJfQp9CmBgYAojIyMgQ2FsY3VsYXRlIGFudGljaXBhdGVkIG51bWJlciBvZiBjZWxscyB5b3UnbGwgZmluZCBpbiBlYWNoIGJpb21hcmsgY2x1c3RlcgpHZXQgIyBjZWxscyBpbiBlYWNoIGNsdXN0ZXIKCmBgYHtyfQp0b3QuY2VsbGNvdW50IDwtIG5yb3coY21wLm9iamVjdEBtZXRhLmRhdGEpCnJlczA1Lmxpc3QgPC0gc29ydCh1bmlxdWUoY21wLm9iamVjdEBtZXRhLmRhdGEkUk5BX3Nubl9yZXMuMC41KSwgZGVjcmVhc2luZyA9IEZBTFNFKQpzYXBwbHkocmVzMDUubGlzdCwgCgkJCSBmdW5jdGlvbih4KXsKCQkJIAlwcmludCgKCQkJIAkJcGFzdGUoCgkJCSAJCQkiY2x1c3RlciIsIHgsICI9IiwgCgkJCSAJCQlucm93KGNtcC5vYmplY3RAbWV0YS5kYXRhW2NtcC5vYmplY3RAbWV0YS5kYXRhJFJOQV9zbm5fcmVzLjAuNSA9PSB4LF0pLCAKCQkJIAkJCSJjZWxscyBvciIsIAoJCQkgCQkJcm91bmQobnJvdyhjbXAub2JqZWN0QG1ldGEuZGF0YVtjbXAub2JqZWN0QG1ldGEuZGF0YSRSTkFfc25uX3Jlcy4wLjUgPT0geCxdKS90b3QuY2VsbGNvdW50KjEwMCwgZGlnaXRzID0gMiksIAoJCQkgCQkJIiUgb2YgdG90YWwiCgkJCSAJCSkKCQkJIAkpCgkJCSB9CgkJCSkKYGBgCgpTbyB3ZSBkaWQgdGhlIGRpbWVuc2lvbmFsIHJlZHVjdGlvbiBiYXNlZCBvbiB0aGUgYmlvbWFyayBSTkFzLCB0aGVuIGRpZCBvdXIgVU1BUCBuZWFyZXN0IG5laWdoYm9yIGNsdXN0ZXJpbmcuCgoKSW4gdGhlIGJpb21hcmsgaGllcmFyY2hjaWFsIGNsdXN0ZXJpbmcgYW5hbHlzaXMgSSBhc3NheWVkIDE2NyBjZWxscy4gVGhlIHNtYWxsZXN0IGNsdXN0ZXIgSSBkZXRlY3RlZCBoYWQgMyBjZWxscywgb3IgMS44JSBvZiB0b3RhbCwgYW5kIHRoaXMgaXMgYW4gdW5jb21mb3J0YWJseSBzbWFsbCBudW1iZXIgb2YgY2VsbHMuIEJhc2VkIG9uIHRoZSBVTUFQIGNhbGN1bGF0aW9ucyBJIHdvdWxkIHRoZXJlZm9yZSBleHBlY3QgdG8gZmluZCAxMSBvciAxMiBvZiB0aGUgcHJlZGljdGVkIDE1IGNsdXN0ZXJzLiBJIGZvdW5kIDEyLCBhbmQgSSBkb24ndCByZWFsbHkgbGlrZSB0aGF0IGxhc3Qgb25lLCBzbyAxMSBvciAxMi4gU2luY2UgSSBkaWQgdGhlIGhpZXJhcmNoY2lhbCBjbHVzdGVyaW5nIHllc3RlcmRheSBhbmQgZGlkIHRoaXMgbWF0aCB0b2RheSwgd2UgY2FuIHNheSBpdCB3YXMgaW5kZXBlbmRlbnQgb2YgdGhlc2UgcmVzdWx0cyBhbmQgdGhlcmVmb3JlIHRvdGFsbHkgbGVnaXQuIFlheSEhCgo=